Если я запускаю команду, du -ah | sort -nr
можно ли сделать так, чтобы она показывала, какая строка в выводе является файлом, а какая папкой? Что-то вроде того, что команда ls -l
показывает, какой файл и папка с d
и -
впереди.
решение1
Это возможно, но не без помощи другой команды. В частности, здесь мы используем GNU awk (это важно, поэтому проверьте свою версию awk)
$ du -ah | sort -nr | awk '{usage=$1; $1="";cmd="file "$0;cmd |& getline type;print usage,type ;close(cmd)}'
24K .: directory
4.0K ./testdir: directory
4.0K ./out.txt: ASCII text
4.0K ./3.txt: ASCII text
4.0K ./2.txt: ASCII text
4.0K ./1.txt: ASCII text
Конечно, этот подход немного несовершенен, так как он, похоже, не работает с именами файлов, содержащими пробелы (над его улучшением все еще работаю).
В качестве альтернативы мы также можем использовать find
команду для поиска всех файлов и запуска file
и du
команд для выполнения наших указаний через -exec
флаг, но это выглядит немного некрасиво (см. историю редактирования). Однако мы могли бы использовать find
флаг -printf
для печати типа файла с %y
форматом для более красивого вывода.
$ find -mindepth 1 -printf "%y\t" -exec du "{}" \; | sort -rn
f 4 ./out.txt
f 4 ./3.txt
f 4 ./2.txt
f 4 ./1.txt
f 0 ./with space.txt
d 4 ./testdir
Очевидно, здесь f
для обычного файла и d
для каталога. Смотрите find
руководство для получения дополнительной информации о флагах и буквах типа файла
решение2
Как говорит Serg, du
не может сделать это само по себе. Для безопасной обработки имен файлов лучше всего разделять их символом ASCII Nul ( \0
), иdu
может сделатьчто. Итак, используя это, а также sort
возможность xargs
обработки ввода с разделителем-нулем:
du -0ah |
sort -zh |
xargs -0 sh -c 'for i; do s=${i%%[[:space:]]*};f=${i#*[[:space:]]}; echo "$s" "$(ls --color -dF "$f")"; done' _
Параметры -0
, -z
и -0
указывают du
, sort
и xargs
использовать ASCII-символ nul в качестве разделителя.
Затем, s=${i%[[:space:]]*}
чтобы получить начало строки до пробела (который является размером), и f=${i#*[[:space:]]}
чтобы получить все остальное (имя файла). Затем мы получаем возможность ls
вывести имя файла с декорированием.
Пример:
$ du -0ah Screenshots | sort -zh | xargs -0 sh -c 'for i; do s=${i%%[[:space:]]*};f=${i#*[[:space:]]}; echo "$s" "$(ls --color -dF "$f")"; done' _
512 Screenshots/desktop.ini*
264K Screenshots/Screenshot (1).png*
269K Screenshots/
Поскольку я использовал ls --color
, я также получил хороший цветной вывод: