拡張子別にグループ化されたファイルサイズ全体を見つける方法

拡張子別にグループ化されたファイルサイズ全体を見つける方法

私は他の同僚と共有するクラスタで働いています。ハードドライブの容量は限られているため(時々いっぱいになる場合があります)、時々セクションをクリーンアップします。これをすばやく実行したいので、これまでは3ヶ月以上100MB以上のファイルのリストを作成し、それがまだ必要かどうかを確認する方法でこれを行いました。

しかし、今では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その作業に適したツールが何であるかわかりません。

答え1

GNUシステムでは:

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

あるいは、GNU拡張をperl避けるのと同じです(まだGNU拡張を使用しますが、これはより広くサポートされています)。-printffind-print0

LC_ALL=C find . -name '?*.*' -type f -print0 |
  perl -0ne '
    if (@s = lstat$_){
      ($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


1例外的にHP / UXによってlstat()報告されたブロックサイズは、stat()512ではなく1024です。 GNUはfindそれを調整して%bまだ512バイト単位の数を表しますが、その場合はperl1024を掛ける必要があります。

答え2

別の解決策は次のとおりです。

find . -type f |  egrep -o "\.[a-zA-Z0-9]+$" | sort -u | LC_ALL=C 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

次に、拡張子を持つファイルを検索して画面に印刷します。

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

次に、内線番号と合計番号を維持したいと思います。

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

同じ行にしてください。

paste - -

答え3

Stephenの解決策ほど良くはありませんが、試してみることができます。

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

各ファイルタイプに対してこのコマンドを実行する必要があります。

答え4

まだコメントを書くのに十分な評判ポイントがないので、ここでStéphane Chazelasの答えを広げましょう。拡張子のないファイル(実行可能ファイルなど)をリストに含めるには、次のコマンドラインを使用できます。

find . -name '*' -type f -printf '%b.%f\0' | awk -F . -v RS='\0' '{if (NF==2) $(NF+1)=" "; s[$NF] += $1; n[$NF]++} END {for (e in s) printf "%15d %6d  %s\n", s[e]*512, n[e], e}' | sort -rn | numfmt --to=iec-i --suffix=B

関連情報