Ваш подход не оправдал не только потому, что оболочки расширила свою команды замены ($(...)
) фронта, но более фундаментально, потому что вы не можете пройти оболочку командной строки до find
find
«S -exec
действие может вызывать только внешние утилиты с буквальных аргументов - единственное небуквальное аргумент Поддерживается ли {}
, представляющее имя файла (ов) в руке.
choroba's answer исправляет немедленную проблему, вызывающую отдельный экземпляр оболочки в каждой итерации, к которому команда оболочки для выполнения передается в качестве аргумента строки в (-exec bash -c '...' \;
).
Хотя это работает (если вы передать значение {}
в качестве аргумента вместо того, чтобы внедрить его в строке командной строки), это также довольно неэффективна, потому что несколько дочерних процессов создаются для каждого входа файл.
(В то время как это способ иметь find
проход (обычно) все входные файлы на (обычно) одного вызова указанной внешней полезности, а именно - с терминатором +
, а не \;
, это не вариант здесь в связи с характером командной строки передается.)
эффективный и надежный [1] реализация, которая минимизирует количество дочерних процессов создано будет выглядеть следующим образом:
Примечание: Я предполагаю, что GNU утилиты здесь, благодаря использованию head -n -1
и sort -h
.
Кроме того, я ограничивая выход find
«s к файлов только (в отличие от каталогов), потому что wc -l
работает только на файлов.
paste <(find . -type f -exec du -h {} +) <(find . -type f -exec wc -l {} + | head -n -1) |
awk -F'\t *' 'BEGIN{OFS="\t"} {sub(" .+$", "", $3); print $1,$2,$3}' |
sort -h -t$'\t' -k1,1
Обратите внимание на использование -exec ... +
, а не -exec ... \;
, который гарантирует, что обычно все входные имена файлов передаются в одного вызова к внешней утилиты (если не все имена файлов помещаются на одной командной строки, вызовы эффективно распределяются, чтобы сделать как можно меньше вызовов).
wc -l {} +
всегда выводит сводную строку, которая head -n -1
удаляет, но также выводит имена файлов после каждого подсчета строк.
paste
объединяет линии от каждой команды (соответствующие входы которой предусмотрены подстановкой процесса <(...)
) в один выходной поток.
Затем команда awk
накладывает посторонние имена файлов, которые начинаются с wc
с конца каждой строки.
Наконец, команда sort
сортирует результат на 1-е (-k1,1
) вкладка разделенных (-t$'\t'
) колонки человеческих считываемых числами (-h
), такие как числа, которые du -h
выходов (например, 1K
).
[1] Как и с любой линии-ориентированной обработки, имена файлов со встроенными символами новой строки не поддерживаются, но я не считаю, что это в реальном мире проблема.
показать нам, что у вас есть – eckes
@eckes, отредактированный с помощью нерабочего кода – Hatshepsut