Перечисление файлов в каталоге, включая содержимое подпапок с сортировкой

9

Я ищу список всего содержимого каталога, включая содержимое вложенных папок, но отсортировано по размеру файла. До сих пор мне удавалось дойти до распечатки и сортировки, хотя и с рекурсивностью ls -lhSR( hэто приятно иметь, но определенно не важно для меня, пока я могу получить размеры файлов). Я, вероятно, упускаю из виду что-то очевидное или спрашиваю о невозможном, но любой совет здесь будет принят с благодарностью.

томы
источник

Ответы:

15

Вы можете использовать найти:

find . -type f -printf "%s %P\n" | sort -n

Необязательно: Чтобы преобразовать байтовые значения в понятный человеку формат, добавьте следующее:

| numfmt --to=iec-i --field=1

Объяснение:

 find in current directory (.) all files (-type f) 

 -printf: suppress normal output and print the following:
     %s - size in bytes
     %P - path to file
     \n - new line

 | sort -n: sort the result (-n = numeric)
pLumo
источник
О, отлично! Большое спасибо, это сделал именно то, что мне нужно!
Томы
3
Я рад, что мой ответ помог вам. Пожалуйста, подумайте о том, чтобы нажать на галочку слева, чтобы отметить принятый ответ. Спасибо.
pLumo
1
@RoVo также было бы неплохо поддержать вопрос, поскольку, учитывая, что вы ответили на него, вы, вероятно, нашли его интересным и полезным.
тердон
Это действительно так, и я сделал это сейчас ;-)
pLumo
@toms Это нормально подождать некоторое время (может быть, день или около того), чтобы принять ответ, даже если он так хорош, как этот. Как только ответ принят, другой ответ не может быть еще лучше. И из-за этого многие люди не удосуживаются представить какие-либо другие ответы, поэтому у нас нет возможности увидеть их, чтобы узнать, если кто-то лучше.
Монти Хардер
7

Поскольку вы не указали конкретную оболочку, вот альтернативный вариант с использованием квалификаторов глобуса zsh с

setopt extendedglob

для рекурсии. Тогда, например:

  1. рекурсивный список простых файлов:

    printf '%s\n' **/*(.)
  2. рекурсивно перечислим обычные файлы, о rdered путем в биговки L ength (т.е. размер):

    printf '%s\n' **/*(.oL)
  3. рекурсивно список обычных файлов, O rdered по де размера гибочного:

    printf '%s\n' **/*(.OL)
  4. Рекурсивно перечислите простые файлы, упорядоченные по уменьшению размера, и выберите первые 3 результата:

    printf '%s\n' **/*(.OL[1,3])

Если вы хотите, чтобы размеры файлов также, то вы можете использовать

du -hb **/*(.OL[1,3])
steeldriver
источник
4

С установленным globstarпараметром оболочки вы можете использовать оболочку:

shopt -s globstar         # don’t match hidden files
shopt -s globstar dotglob # match hidden files
stat -c"%s %n" **/* | sort -n

Если вы попытаетесь сделать это с большим количеством файлов, вы получите ошибку «Список аргументов слишком длинный». Чтобы обойти это, вы можете использовать printfи xargs:

printf "%s\0" **/* | xargs -0 stat -c"%s %n" | sort -n

Я только что понял, что это печатает также и каталоги (размером 4096 байт) - если вы этого не хотите, используйте вместо этого:

stat -c"%A %s %n" **/* | sed '/^d/d;s/\S* //' | sort -n
printf "%s\0" **/* | xargs -0 stat -c"%A %s %n" | sed '/^d/d;s/\S* //' | sort -n

Пример запуска

$ tree
.
├── edits.png
├── makescript
├── new
   └── edits.png
└── test
    └── 1.png

2 directories, 4 files
$ stat -c"%s %n" **/* | sort -n
0 test/1.png
43 makescript
2160 edits.png
2160 new/edits.png
4096 new
4096 test
$ stat -c"%A %s %n" **/* | sed '/^d/d;s/\S* //' | sort -n
0 test/1.png
43 makescript
2160 edits.png
2160 new/edits.png
Десерт
источник
Хорошее решение. По сравнению с поиском, он не содержит скрытых файлов, как этого добиться?
pLumo
@RoVo Всегда забывайте об этом - вам просто нужно установить параметр dotglobоболочки, смотрите мой обновленный ответ.
десерт
Вместо разборки каталогов после факта с помощью sed, вы можете рассмотреть что-то вродеprintf "%s\0" **/* | xargs -0 sh -c 'for f; do [ -d "$f" ] || stat -c "%s %n" "$f"; done' sh | sort -n
steeldriver
Вы можете использовать, ls -lhSd **/*если вы не против иметь каталоги как часть списка. Или, если ни одно из имен ваших каталогов не содержится .в них, и все файлы, которые вы хотите сделать , вы можете ll -hS **/*.*, или аналогичные.
Питер Кордес
превратил это в ответ
Питер Кордес
3

Если у вас нет zsh, вы все равно можете использовать du+ sort:

  1. Удобочитаемые размеры, включая совокупные размеры каталогов:

    du --apparent-size -ah0 . | sort -zh | xargs -0L1
    
  2. Только файлы (используя find):

    find . -type f -print0 |
      du --files0-from=- --apparent-size -ah0 |
      sort -zh |
      xargs -0L1
    

В обеих случаях, я решил использовать завершающий нуль линии ( -0, -z, -print0опционы), чтобы быть безопасными против всех действительных имен файлов.

Мур
источник
0

Для быстрого интерактивного использования на деревьях каталогов, которые не слишком велики,shopt -s globstar это действительно приятно. Глоб не может отфильтровывать каталоги по типу, но если вы используете его, ls -dто lsпросто напечатает имя каталога, а не его содержимое.

Предполагая ваш ll псевдоним включает в себя -lh:

  # with  shopt -s globstar   in your .bashrc
ll -rSd **/*

даст вам вывод, как это (из моего каталога code-golf), но с цветной подсветкой (так что каталоги легче увидеть). Обратите внимание, что сортировка по размеру файла происходила по подкаталогам.

drwxr-xr-x 1 peter peter   70 Jun  8 07:56 casexchg
...
drwxr-xr-x 1 peter peter  342 Mar 13 18:47 parity-party
-rw-r--r-- 1 peter peter  387 Jul 29  2017 likely.cpp
-rw-r--r-- 1 peter peter  416 Aug 31  2017 true-binary.asm~
-rw-r--r-- 1 peter peter  447 Feb 23 20:14 weight-of-zero.asm
...
-rw-r--r-- 1 peter peter 6.4K Jun  1  2017 string-exponential.asm
-rwxr-xr-x 1 peter peter 6.7K Aug 31  2017 true-binary
-rwxr-xr-x 1 peter peter 6.8K Sep 17  2017 dizzy-integer
-rw-r--r-- 1 peter peter 7.5K Jul 24  2017 fibonacci/fibonacci-1G.v3-working-32b-stack-except-output.asm
-rw-r--r-- 1 peter peter 8.4K Jul 25  2017 fibonacci/perf.32bit-pop-114limb.sub-cmc.1G~
-rw-r--r-- 1 peter peter 8.4K Jul 25  2017 fibonacci/perf.32bit-pop-114limb.sub-cmc.1G
-rwxr-xr-x 1 peter peter 8.4K May 19 04:29 a.out
-rw-r--r-- 1 peter peter 8.9K Jul 25  2017 fibonacci/perf.python-xnor-2n
-rw-r--r-- 1 peter peter 9.5K Jul 26  2017 fibonacci/fibonacci-1G-performance.asm
-rwxr-xr-x 1 peter peter 9.6K Apr 12 23:25 empty-args
-rw-r--r-- 1 peter peter 9.7K Dec 18 17:00 bubblesort.asm
-rwxr-xr-x 1 peter peter 9.9K Feb  6 23:34 parity-party/a.out
-rw-r--r-- 1 peter peter 9.9K Jul 25  2017 fibonacci/fibonacci-1G-performance.asm~
...

Вы можете отфильтровать каталоги, пропуская через grep -v '^d'

Иногда вы можете использовать глоб, который соответствует только файлам, а не каталогам, если ваши имена файлов имеют шаблон. Например ll -rSd **/*.jpg, или даже **/*.*работает, если ни одно из ваших имен каталогов нет .в них, и все файлы, которые вы хотите сделать .

(Для людей с опытом работы в DOS: в этом нет ничего волшебного *.* Unix . Он просто соответствует любой записи каталога, содержащей буквальную точку. Но кроме исполняемых файлов и иногда текстовых файлов, обычно дают расширения для имен файлов.)

@dessert указывает, что вам нужно, shopt -s dotglobчтобы он соответствовал всем файлам.


С GNU find

Если в одной lsкомандной строке не слишком много файлов , find -exec ls {} +поместите их в командную строку, где их lsможно отсортировать.

find -not -type d -exec ls --color -lrSh {} +

Использование -not -type dвместо-type f избегать игнорирования символических ссылок, именованных каналов, сокетов, файлов устройств и всего, что у вас есть в ваших каталогах.


С du:

du -ach | sort -h
....
4.0K    x86-modedetect-polyglot.o
8.0K    ascii-compress-base.asm
8.0K    dizzy-integer
8.0K    stopwatch-rdtsc.asm
8.0K    string-exponential.asm
8.0K    true-binary
12K     a.out
12K     bubblesort.asm
12K     casexchg
12K     empty-args
100K    parity-party
220K    fibonacci
628K    total

Теперь имена каталогов сортируются в списке, чтобы суммировать все их содержимое, но отдельные файлы по-прежнему включены.

sort -h, ака --human-numeric-sort, сортирует числа с суффиксами размера какdu -h печатные издания. Это идеально подходит для использования с du.

Я часто использую du -sch * | sort -h, или*/ чтобы получить только каталоги.

du -sch **/* | sort -h даст вам вышеупомянутый вывод, если вы забудете, что du есть -aопция.

(Я только нашел время, чтобы найти его, потому что отправляю ответ. Для интерактивного использования я бы, наверное, просто использовал du -sch **/*.

Питер Кордес
источник