Сортировка файлов по размеру рекурсивно


80

Мне нужно найти самые большие файлы в папке.
Как рекурсивно сканировать папку и сортировать содержимое по размеру?

Я пытался использовать ls -R -S, но это список каталогов, а также.
Я также пытался использовать find.


1
Вы хотите перечислить файлы в каждом подкаталоге отдельно или вы хотите найти все файлы во всех подкаталогах и перечислить их по размеру независимо от того, в каком подкаталоге они находятся? Кроме того, что вы подразумеваете под "каталогом" и "папкой"? Вы, кажется, используете их, чтобы описать разные вещи.
Тердон

Вы хотите сказать, что хотите просто перечислить файлы в данном каталоге, а также файлы в его подкаталогах, не показывая только подкаталоги? Пожалуйста, попробуйте и уберите свой вопрос, это не очень понятно.
SLM

Ответы:


93

Вы также можете сделать это просто du. Просто чтобы быть в безопасности, я использую эту версию du:

$ du --version
du (GNU coreutils) 8.5

Подход:

$ du -ah ..DIR.. | grep -v "/$" | sort -rh

Разбивка подхода

Команда du -ah DIRвыдаст список всех файлов и каталогов в данном каталоге DIR. -hБудет производить читаемые размеры человека , которые я предпочитаю. Если вы не хотите их, тогда отпустите этот переключатель. Я использую head -6только, чтобы ограничить количество продукции!

$ du -ah ~/Downloads/ | head -6
4.4M    /home/saml/Downloads/kodak_W820_wireless_frame/W820_W1020_WirelessFrames_exUG_GLB_en.pdf
624K    /home/saml/Downloads/kodak_W820_wireless_frame/easyshare_w820.pdf
4.9M    /home/saml/Downloads/kodak_W820_wireless_frame/W820_W1020WirelessFrameExUG_GLB_en.pdf
9.8M    /home/saml/Downloads/kodak_W820_wireless_frame
8.0K    /home/saml/Downloads/bugs.xls
604K    /home/saml/Downloads/netgear_gs724t/GS7xxT_HIG_5Jan10.pdf

Достаточно просто отсортировать от наименьшего к большому:

$ du -ah ~/Downloads/ | sort -h | head -6
0   /home/saml/Downloads/apps_archive/monitoring/nagios/nagios-check_sip-1.3/usr/lib64/nagios/plugins/check_ldaps
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/0/index/write.lock
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/0/translog/translog-1365292480753
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/1/index/write.lock
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/1/translog/translog-1365292480946
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/2/index/write.lock

Переверните его, от самого большого до самого маленького:

$ du -ah ~/Downloads/ | sort -rh | head -6
10G /home/saml/Downloads/
3.8G    /home/saml/Downloads/audible/audio_books
3.8G    /home/saml/Downloads/audible
2.3G    /home/saml/Downloads/apps_archive
1.5G    /home/saml/Downloads/digital_blasphemy/db1440ppng.zip
1.5G    /home/saml/Downloads/digital_blasphemy

Не показывайте мне каталог, только файлы:

$ du -ah ~/Downloads/ | grep -v "/$" | sort -rh | head -6 
3.8G    /home/saml/Downloads/audible/audio_books
3.8G    /home/saml/Downloads/audible
2.3G    /home/saml/Downloads/apps_archive
1.5G    /home/saml/Downloads/digital_blasphemy/db1440ppng.zip
1.5G    /home/saml/Downloads/digital_blasphemy
835M    /home/saml/Downloads/apps_archive/cad_cam_cae/salome/Salome-V6_5_0-LGPL-x86_64.run

Если вы просто хотите, чтобы список от самого маленького к самому большому, но из шести самых вредных файлов вы могли поменять переключатель сортировки, drop ( -r) и использовать tail -6вместо head -6.

$ du -ah ~/Downloads/ | grep -v "/$" | sort -h | tail -6
835M    /home/saml/Downloads/apps_archive/cad_cam_cae/salome/Salome-V6_5_0-LGPL-x86_64.run
1.5G    /home/saml/Downloads/digital_blasphemy
1.5G    /home/saml/Downloads/digital_blasphemy/db1440ppng.zip
2.3G    /home/saml/Downloads/apps_archive
3.8G    /home/saml/Downloads/audible
3.8G    /home/saml/Downloads/audible/audio_books

14
Эта grep -v "/$"часть, кажется, не выполняет то, что вы ожидали, так как в каталогах нет косой черты. Кто-нибудь знает, как исключить каталоги из результатов?
Ян Вархол

@JanekWarchol - какую версию coreutils вы используете?
SLM

Я на 8.13. Но в любом случае, вывод в вашем ответе также не имеет конечных /s - например, /home/saml/Downloads/audibleкажется, что это каталог, но у него нет косой черты. /home/saml/Downloads/Имеет только косую черту, но это, вероятно, потому, что вы указали косую черту при указании аргумента для начального du.
Ян Вархол

1
Это находит и dirs
ekerner

1
Это не только список файлов, но и список каталогов :(
Роман Гауфман

21

Если вы хотите найти все файлы в текущем каталоге и его подкаталогах и перечислить их в соответствии с их размером (без учета их пути), и при условии, что ни одно из имен файлов не содержит символов новой строки, с помощью GNU findвы можете сделать это:

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

В man findсистеме GNU:

   -printf format
          True; print format  on  the  standard  output,
          interpreting  `\'  escapes and `%' directives.
          Field widths and precisions can  be  specified
          as  with the `printf' C function.  Please note
          that many of the  fields  are  printed  as  %s
          rather  than  %d, and this may mean that flags
          don't work as you  might  expect.   This  also
          means  that  the `-' flag does work (it forces
          fields to be  left-aligned).   Unlike  -print,
          -printf  does  not add a newline at the end of
          the string.  The escapes and directives are:

          %p     File's name.
          %s     File's size in bytes.

От man sort:

   -n, --numeric-sort
          compare according to string numerical value

К сожалению, не работает на Mac, показывает: find: -printf: неизвестный основной или оператор
Roman Gaufman

@RomanGaufman да, поэтому в ответе указывается GNU find. Если вы установите инструменты GNU на свой Mac, он также будет работать там.
Тердон

11

Попробуйте следующую команду:

ls -1Rhs | sed -e "s/^ *//" | grep "^[0-9]" | sort -hr | head -n20

Он будет рекурсивно перечислять 20 самых больших файлов в текущем каталоге.

Примечание. Параметр -hfor sortнедоступен в OSX / BSD, поэтому необходимо установить sortс coreutils(например, через brew) и применить локальный путь к PATHбину, например,

export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" # Add a "gnubin" for coreutils.

Альтернативно используйте:

ls -1Rs | sed -e "s/^ *//" | grep "^[0-9]" | sort -nr | head -n20

Для самых больших каталогов используйте du, например:

du -ah . | sort -rh | head -20

или же:

du -a . | sort -rn | head -20

3
Отлично, это первое решение, которое работает на Mac и не показывает каталоги :) - спасибо!
Роман Гауфман

как фильтр показать только файл с количеством строк> = X? (X = 0 для примера)
Матрица

7

Это позволит найти все файлы рекурсивно и отсортировать их по размеру. Он распечатывает файлы всех размеров в килобайтах и ​​округляет их, чтобы вы могли видеть файлы размером 0 КБ, но он был достаточно близок для моего использования и работает на OSX.

find . -type f -print0 | xargs -0 ls -la | awk '{print int($5/1000) " KB\t" $9}' | sort -n -r -k1


работал на Ubuntu 14.04 тоже!
Дэвид Лэм

Здесь перечислены каталоги, а не только файлы :(
Роман Гауфман

@RomanGaufman - спасибо за отзыв! из моих тестов find . -type fнаходит файлы ... он работает рекурсивно, вы правы, но в нем перечислены все файлы, которые он находит, а не сами каталоги
Брэд Паркс

Xargs был использован в 1980-х годах. Это плохая идея с 1989 года, когда Дэвид Корн представил execplus.
Шили

5

С помощью zshвы найдете самый большой файл (с точки зрения видимого размера, например, размер столбца в ls -lвыводе, а не использования диска) с

ls -ld -- **/*(DOL[1])

Для 6 крупнейших:

ls -ld -- **/*(DOL[1,6])

Для сортировки тех , по размеру файла, вы можете использовать ls«ы -Sвариант. Некоторые lsреализации также имеют -Uвозможность lsне сортировать список (так как он уже отсортирован по размеру zsh).


3

Простое решение для Mac / Linux, которое пропускает каталоги:

find . -type f -exec du -h {} \; | sort -h


0

Это невероятно общая потребность по разным причинам (мне нравится находить самую последнюю резервную копию в каталоге), и это удивительно простая задача.

Я собираюсь представить решение Linux, которое использует утилиты find, xargs, stat, tail, awk и sort.

Большинство людей предоставили несколько уникальных ответов, но я предпочитаю свои, потому что он правильно обрабатывает имена файлов, и вариант использования может быть легко изменен (изменить статистику и отсортировать аргументы)

Я также предоставлю решение Python, которое позволит вам использовать эту функциональность даже в Windows

Linux решение для командной строки

Рекурсивно вернуть весь список только файлов из каталога, отсортированный по размеру файла

find . -type f -print0 | xargs -0 -I{} stat -c '%s %n' {} | sort -n

То же, что и раньше, но на этот раз верните самый большой файл.

# Each utility is split on a new line to help 
# visualize the concept of transforming our data in a stream
find . -type f -print0 | 
xargs -0 -I{} stat -c '%s %n' {} | 
sort -n | 
tail -n 1 |
awk '{print $2}'

Тот же самый шаблон, но теперь выберите самый новый файл вместо самого большого

# (Notice only the first argument of stat changed for new functionality!)
find . -type f -print0 | xargs -0 -I{} stat -c '%Y %n' {} | 
sort -n | tail -n 1 | awk '{print $2}'

Объяснение:

  1. find: рекурсивно находит все файлы из текущего каталога и печатает их с нулевым символом
  2. xargs: утилита для выполнения команд, используя аргументы из стандартного ввода. Для каждой строки вывода мы хотим запустить утилиту stat для этого файла
  3. stat: Stat - универсальная команда, которая имеет так много вариантов использования. Я распечатываю два столбца, первый столбец - размер блока (% s), а второй столбец - имя файла (% n)
  4. sort: сортировка результатов с помощью числового переключателя. Поскольку первый аргумент является целым числом, наши результаты будут отсортированы правильно
  5. tail: выберите только последнюю строку вывода (так как список отсортирован, это самый большой файл!)
  6. awk: выберите второй столбец, который содержит имя файла и является самым большим файлом в рекурсивном каталоге.

Решение Python

#!/usr/bin/env python
import os, sys
files = list()
for dirpath, dirname, filenames in os.walk(sys.argv[1]):
    for filename in filenames:
        realpath = os.path.join(dirpath, filename)
        files.append(realpath)
files_sorted_by_size = sorted(files, key = lambda x: os.stat(x).st_size)
largest_file = files_sorted_by_size[-1]
print(largest_file)

Этот сценарий требует немного больше времени для объяснения, но, по сути, если вы сохраните его как сценарий, он выполнит поиск по первому аргументу, указанному в командной строке, и вернет самый большой файл в этом каталоге. Скрипт не проверяет ошибки, но он должен дать вам представление о том, как подойти к этому в Python, который дает хороший платформо-независимый способ решения этой проблемы.



0

Попробуйте команду ниже с опцией сортировки, чтобы иметь папки с размером в порядке возрастания

du -sh * | sort -sh


-1

То, что работает на любой платформе, кроме AIX и HP-UX:

find . -ls | sort +6 | tail
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.