コマンドプロンプトからファイルサイズの分布を生成する


16

私は数百万のファイルを持つファイルシステムを持っているので、特定のディレクトリでファイルサイズの分布を再帰的に見たいです。これはbash / awk fuで完全に実行できるように感じますが、手を使うこともできます。基本的には次のようなものが欲しいです:

1KB: 4123
2KB: 1920
4KB: 112
...
4MB: 238
8MB: 328
16MB: 29138
Count: 320403345

ループと条件付きのlog2ファイルサイズfooがあれば、これはそれほど悪くないはずですが、そこまで到達することはできません。

関連質問:xバイトより大きい/小さいファイルを見つけるにはどうすればよいですか?

回答:


21

これはかなりうまくいくようです:

find . -type f -print0 | xargs -0 ls -l | awk '{size[int(log($5)/log(2))]++}END{for (i in size) printf("%10d %3d\n", 2^i, size[i])}' | sort -n

出力は次のようになります。

         0   1
         8   3
        16   2
        32   2
        64   6
       128   9
       256   9
       512   6
      1024   8
      2048   7
      4096  38
      8192  16
     16384  12
     32768   7
     65536   3
    131072   3
    262144   3
    524288   6
   2097152   2
   4194304   1
  33554432   1
 134217728   4
ここで、左側の数字はその値からその値の2倍までの範囲の下限であり、右側の数字はその範囲内のファイルの数です。


lsの代わりにfindを使用するように回答を編集して、再帰的でディレクトリカウントを行わないようにしました。左側の列の出力をきれいにしたい人はいますか?
notpeter

しかし、元の質問は「特定のディレクトリでのファイルサイズの分布」に関するものであったため、lsをに変更しても問題ありませんfind。元の状態に戻しています。
ゲイリージョン

@notpeter:申し訳ありませんが、質問の著者としてあなたを認識しませんでした。再帰的に検索するように回答を変更しました。私のシステムでは、しかし、使用してはxargsいるかなり速くよりも-exec、私はその方法を使用して、。
ゲイリージョン

1
心配ない。これで、コメントを削除するだけで、常に正しい答えになりました。;)
notpeter

14

garyjohnの答えに基づいて、ここに1行があります。これは出力を人間が読める形式にフォーマットします。

find . -type f -print0 | xargs -0 ls -l | awk '{ n=int(log($5)/log(2)); if (n<10) { n=10; } size[n]++ } END { for (i in size) printf("%d %d\n", 2^i, size[i]) }' | sort -n | awk 'function human(x) { x[1]/=1024; if (x[1]>=1024) { x[2]++; human(x) } } { a[1]=$1; a[2]=0; human(a); printf("%3d%s: %6d\n", a[1],substr("kMGTEPYZ",a[2]+1,1),$2) }'

これが拡張バージョンです:

find . -type f -print0                                                   \ 
 | xargs -0 ls -l                                                        \
 | awk '{ n=int(log($5)/log(2));                                         \
          if (n<10) n=10;                                                \
          size[n]++ }                                                    \
      END { for (i in size) printf("%d %d\n", 2^i, size[i]) }'           \
 | sort -n                                                               \ 
 | awk 'function human(x) { x[1]/=1024;                                  \
                            if (x[1]>=1024) { x[2]++;                    \
                                              human(x) } }               \
        { a[1]=$1;                                                       \ 
          a[2]=0;                                                        \
          human(a);                                                      \
          printf("%3d%s: %6d\n", a[1],substr("kMGTEPYZ",a[2]+1,1),$2) }' 

最初awkに、1kb未満のすべてのファイルを1か所に収集するための最小ファイルサイズを定義しました。2番目awkhuman(x)は、人間が読めるサイズを作成する関数が定義されています。この部分は、https//unix.stackexchange.com/questions/44040/a-standard-tool-to-convert-a-byte-count-into-human-kib-mib-etcの回答の1つに基づいています-like-du-ls1

サンプル出力は次のようになります。

  1k:    335
  2k:     16
 32k:      5
128k:     22
  1M:     54
  2M:     11
  4M:     13
  8M:      3

2

これを試して:

find . -type f -exec ls -lh {} \; | 
 gawk '{match($5,/([0-9.]+)([A-Z]+)/,k); if(!k[2]){print "1K"} \
        else{printf "%.0f%s\n",k[1],k[2]}}' | 
sort | uniq -c | sort -hk 2 

出力

 38 1K
 14 2K
  1 30K
  2 62K
  12 2M
  2 3M
  1 31M
  1 46M
  1 56M
  1 75M
  1 143M
  1 191M
  1 246M
  1 7G

説明 :

  • find . -type f -exec ls -lh {} \;:十分に簡単で、現在のディレクトリでファイルを見つけて実行ls -lhする

  • match($5,/([0-9.]+)([A-Z]+)/,k);:これはファイルサイズを抽出し、各一致を配列に保存しますk

  • if(!k[2]){print "1K"}k[2]未定義の場合、ファイルサイズは<1Kです。私はあなたがそのような小さなサイズを気にしないと想像しているので、スクリプトは1Kサイズが1K未満のすべてのファイルに対して印刷します。

  • else{printf "%.0f%s\n",k[1],k[2]} :ファイルが1Kより大きい場合、ファイルサイズを最も近い整数に丸め、その修飾子(K、M、またはG)とともに印刷します。

  • sort | uniq -c :印刷された各行(ファイルサイズ)の出現回数をカウントします。

  • sort -hk 2:人間が読める形式の2番目のフィールドに従ってソートします。このように、7Gはの後にソートされ8Mます。


私は説明に感謝します、それを理解しようとしている人々にとって役立つと思います。それはあなたのスクリプトが2つの理由で私のために機能しないということです1)私のGNU LSは古く、そのため「ls -lh」(K / M / G / Tではないバイト)と2)のために異なる人間が読めるサイズの出力を与えますバケットが多すぎます。ファイルサイズが1K〜1Gの場合、バケットは2000個あり、その半分は1KB、半分は1MBです。「uniq -c」については、それは私にとって新しいことです。
notpeter
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.