Как найти общий размер файла, сгруппированный по расширению


12

Я работаю над кластером, которым поделились другие коллеги. Жесткий диск ограничен (и в некоторых случаях он был переполнен), поэтому я иногда очищаю свою часть. Я хочу сделать это быстро, поэтому до сих пор я делаю это, создавая список файлов размером более 100 МБ старше 3 месяцев, и я вижу, нужны ли они мне по-прежнему.

Но теперь я думаю, что может быть папка с> 1000 файлами меньшего размера, которые мне не хватает, поэтому я хочу получить простой способ выяснить, так ли это. По тому, как я генерирую данные, это поможет получить список общего размера для каждого расширения. В контексте этого вопроса «расширение» - все, что находится за последней точкой в ​​имени файла.

Предположим, у меня есть несколько папок с несколькими файлами:

folder1/file1.bmp   40 kiB
folder1/file2.jpg   20 kiB
folder2/file3.bmp   30 kiB
folder2/file4.jpg    8 kiB

Можно ли составить список общего размера файлов для каждого расширения файла, так вот так:

bmp 70 kiB
jpg 28 kiB

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

Я уже пролистал справочные страницы ls, duи find, но я не знаю, какой инструмент подходит для этой работы ...


Этот вопрос не был бы неправильным на codegolf.stackexchange.com :)
Даг Маклин

@DougMcLean: вы можете разместить его там. ;)

Ответы:


16

В системе GNU:

find . -name '?*.*' -type f -printf '%b.%f\0' |
  awk -F . -v RS='\0' '
    {s[$NF] += $1; n[$NF]++}
    END {for (e in s) printf "%15d %4d %s\n", s[e]*512, n[e], e}' |
  sort -n

Или то же самое perl, избегая -printfрасширения GNU find(все еще использующего расширение GNU -print0, но это более широко поддерживается в настоящее время):

find . -name '?*.*' -type f -print0 |
  perl -0ne '
    if (@s = stat$_){
      ($ext = $_) =~ s/.*\.//s;
      $s{$ext} += $s[12];
      $n{$ext}++;
    }
    END {
      for (sort{$s{$a} <=> $s{$b}} keys %s) {
        printf "%15d %4d %s\n",  $s{$_}<<9, $n{$_}, $_;
      }
    }'

Это дает вывод как:

          12288    1 pnm
          16384    4 gif
         204800    2 ico
        1040384   17 jpg
        2752512   83 png

Если хотите KiB, MiB... суффиксы, отправьте numfmt --to=iec-i --suffix=B.

%b*512дает использование диска, но обратите внимание, что если файлы жестко связаны несколько раз, они будут подсчитаны несколько раз, поэтому вы можете увидеть расхождение с тем, какие duотчеты.


Сбой на MacOS (найти: -printf: неизвестный первичный или оператор)
MichaelCodes

1
@MichaelCodes, yes -printfотносится к GNU find, поэтому я и сказал о системе GNU .
Стефан

@MichaelCodes, смотрите edit с perlальтернативой, которая должна работать даже на macOS.
Стефан

Что такое 1,4,2,17? Количество файлов для каждого типа?
Хорхе Корнехо Беллидо

3

Вот еще одно решение:

find . -type f |  egrep -o "\.[a-zA-Z0-9]+$" | sort -u | xargs -I '%' find . -type f -name "*%" -exec du -ch {} + -exec echo % \; | egrep "^\.[a-zA-Z0-9]+$|total$" | uniq | paste - -

Часть, которая получает расширения:

find . -type f |  egrep -o "\.[a-zA-Z0-9]+$" | sort -u

Затем найдите файлы с расширением и распечатайте их на экране:

xargs -I '%' find . -type f -name "*%" -exec du -ch {} + -exec echo % \;

Далее мы хотим сохранить расширение и итог:

egrep "^\.[a-zA-Z0-9]+$|total$" | uniq

и держите его в одной строке:

paste - -

Работает на MacOS.
MichaelCodes

2

Не так хорошо, как решение Стефана, но вы можете попробовать

find . -type f -name "*.png" -print0 | xargs -0r du -ch | tail -n1

где вы должны запустить это для каждого типа файлов.


1
Это предполагает, что png-файлов достаточно мало, и duвыполняется только один вызов. В GNU xargsвы бы хотели добавить -rфлаг, чтобы du не запускался, когда файла нет (в противном случае вы бы в конечном итоге использовали диск текущего каталога). Вы можете добавить -type fили, ! type dчтобы избежать подсчета файлов, которые находятся в каталогах, имя которых заканчивается на .png.
Стефан Шазелас

это ищет только одно конкретное расширение.
Рахул

Вот что я написал. Нужно было обернуть его в скрипт, который перебирает все применимые расширения, чтобы получить «законченное» решение.
контррежим
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.