Как лучше всего напечатать список 10 самых больших файлов в оболочке POSIX? Должно быть что-то более элегантное, чем мое текущее решение:

DIR="."
N=10
LIMIT=512000

find $DIR -type f -size +"${LIMIT}k" -exec du {} \; | sort -nr | head -$N | perl -p -e 's/^\d+\s+//' | xargs -I {} du -h {}

Где LIMIT — пороговое значение размера файла для ограничения результатов поиска.

7
Matti 6 Мар 2011 в 23:45
Да (см. скрипт выше). Проблема в том, что du не сортирует результаты.
 – 
Matti
6 Мар 2011 в 23:54
Учитывая случайный блок в файловой системе, можно ли найти связанное с ним имя файла? (Для тех блоков, которые находятся в файле/каталоге). Если это так, это был бы очень эффективный способ найти самые большие файлы. (Я почти уверен, что ответ «Нет», я гуглил раньше, но, возможно, SO что-то найдет.) Зависит от файловой системы?
 – 
Aaron McDaid
8 Янв 2012 в 19:13

1 ответ

Редактировать:

Использование утилит Gnu (du и sort):

du -0h | sort -zrh | tr '\0' '\n'

Это использует нулевой разделитель для передачи информации между du и sort и использует tr для преобразования нулей в символы новой строки. Пустые значения позволяют этому конвейеру обрабатывать имена файлов, которые могут включать символы новой строки. Обе опции -h заставляют вывод быть в удобочитаемой форме.

Оригинал:

Это использует awk для создания дополнительных столбцов для ключей сортировки. Он вызывает du только один раз. Вывод должен выглядеть точно так же, как du.

Я разбил его на несколько строк, но его можно объединить в одну строку.

du -h |
  awk '{printf "%s %08.2f\t%s\n", 
    index("KMG", substr($1, length($1))),
    substr($1, 0, length($1)-1), $0}' |
  sort -r | cut -f2,3

Пояснение:

  • НАЧАЛО - создать строку для индексации для замены 1, 2, 3 на К, М, Г для группировки по единицам, если единицы нет (размер меньше 1К), то совпадения нет и возвращается ноль (идеально! )
  • вывести новые поля - единицу измерения, значение (чтобы альфа-сортировка работала правильно, она дополнена нулями, фиксированная длина) и исходная строка
  • индексировать последний символ поля размера
  • вытащить числовую часть размера
  • отсортировать результаты, отбросить лишние столбцы

Попробуйте без команды cut, чтобы увидеть, что она делает.

Редактировать:

Вот версия, которая выполняет сортировку в сценарии AWK и не нуждается в вырезании (требуется GNU AWK (gawk) для поддержки asorti):

du -h0 |
   gawk 'BEGIN {RS = "\0"}
        {idx = sprintf("%s %08.2f %s", 
         index("KMG", substr($1, length($1))),
         substr($1, 0, length($1)-1), $0);
         lines[idx] = $0}
    END {c = asorti(lines, sorted);
         for (i = c; i >= 1; i--)
           print lines[sorted[i]]}'

Изменить: добавлено разделение нулевых записей для обработки потенциальных имен файлов, которые включают новые строки. Требуется GNU du и gawk.

7
Dennis Williamson 24 Авг 2021 в 19:20
awk: calling undefined function asorti input record number 75, file source line number 5
 – 
Alexey Sh.
12 Фев 2019 в 23:44
@AlexeySh.: Извините, я изменю свой ответ, указав, что GNU AWK (gawk) требуется для asorti.
 – 
Dennis Williamson
12 Фев 2019 в 23:49