次のシェルスクリプトは、20MBを超えるすべてのファイルをどのように検索しますか?

次のシェルスクリプトは、20MBを超えるすべてのファイルをどのように検索しますか?

次のようにすると、サイズが20Mbを超えるファイルをすべて見つけることができるという記事を見ました。

find / -type f -size +20000k -exec ls -lh {} \; 2> /dev/null   | awk '{ print $NF ": " $5 }'  | sort -hrk 2,2

うまくいくようですが、「+20000k」の後に何をしているのかわかりません。

答え1

find / -type f -size +20000k -exec ls -lh {} \; 2> /dev/null   | awk '{ print $NF ": " $5 }'  | sort -hrk 2,2
  • /: ホームディレクトリで開始を検索
  • -type f:一般ファイルのみを探す
  • -size +20000k:サイズが20000k以上です。
  • -exec ls -lh {} \;:見つかった各ファイルに対して実行されますls -lh。つまり、長い形式と人間が読めるサイズ(サフィックス「K」、「M」、「G」などを含む)としてリストされます。
  • 2>/dev/nullfindエラーメッセージが生成されたらブラックホールにリダイレクトします。
  • |find結果を次のコマンドにパイプします(この場合はawk)。
  • awk '{print $NF ": " $5}':出力の最後のフィールド、ls -lhコロン、5番目のフィールドを印刷します。最後のフィールドはファイル名で、5番目のフィールドはファイルサイズ(前述の人が読める形式)です。
  • |:結果を再パイプします(今回はawkからからsort)。
  • sort -hrk 2,2:2番目のフィールドのみを考慮して、人間が読める数字に基づいて逆順に結果をソートします。

ノート

awkコマンドを使用せずに、これを簡単かつ迅速に実行できますsort

find / -type f -size +20000k -exec ls -Shs {} +

どこ

  • ls -Shs:ファイルを一覧表示し、サイズで並べ替えながら、人間が読める形式でサイズを印刷します。
  • {} +見つかったファイルをfindリストに追加し、リストls全体の最後にのみ実行します。各ファイルを{} \;個別に実行する場合。ls

これら2つのコマンドの唯一の違いは、前者の場合、サイズは第2の列に印刷されるのに対し、後者の場合は第1の列に印刷されることである。ただし、ファイル名またはディレクトリ名にスペースが含まれている場合、出力ls -lにはファイルごとに異なる数の列があるため、出力はawk多少ランダムになります。つまりlsの出力を解析しないでください。

答え2

これ

-exec ls -lh {} \;

ls -lhfindは見つかった各ファイルに対してコマンドを実行します{}。 「\;」は、各ファイルに個別にコマンドを提供することを意味します。マニュアルページから:

   -exec command ;
          Execute command; true if 0 status is returned.   All  following
          arguments  to  find  are  taken  to be arguments to the command
          until an argument consisting of `;' is encountered.  The string
          `{}'  is  replaced  by  the  current  file name being processed
          everywhere it occurs in the arguments to the command, not  just
          in  arguments  where  it is alone, as in some versions of find.
          Both of these constructions might need to be  escaped  (with  a
          `\')  or  quoted  to  protect them from expansion by the shell.
          See the EXAMPLES section for examples of the use of  the  -exec
          option.   The  specified  command  is run once for each matched
          file.  The command  is  executed  in  the  starting  directory.
          There  are unavoidable security problems surrounding use of the
          -exec action; you should use the -execdir option instead.

この2> /dev/nullセクションでは、エラー(読み取れないディレクトリなど)が削除されたことを確認します(/dev/null)。

ls -lhファイルの実際の出力は次のとおりです。

-rw-rw-r--  1 anthon users   1,2K Aug 24  2013 sizes.data1

awk次に、ファイル名(NFはフィールド数を表します)と5番目のフィールド(たとえばsizes.data1: 1.2K:)を抽出するコマンドを入力します。

これらの名前:サイズの組み合わせは、sort2番目のフィールド()-k 2,2のソートにパイプされます。ソートのための-hは、リバースソートls -lhのための-hの出力と一致します-r

答え3

-exec ls -lh{}\; /dev/empty

20 MB を超えるファイルごとに -l オプションと -h オプションを指定して ls コマンドを実行し、エラーを /dev/null にリダイレクトします。

    -l     use a long listing format

    -h, --human-readable
          with -l, print sizes in human readable format (e.g., 1K 234M 2G)

これにより、次のような出力が生成されます。

-rw-r--r--. 1 root root 58M 2012年10月15日/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/rt.jar

awkコマンド:

awk '{印刷 $NF ": " $5 }'

ファイル名とサイズを印刷します。 $ NFは最後の列を表し、$ 5は5番目の列を表します。

/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/rt.jar:58M

最後のコマンド:

ソート時間 2,2

2番目の列(サイズなど)を逆方向に並べ替えます。

   -h, --human-numeric-sort
          compare human readable numbers (e.g., 2K 1G)
   -r, --reverse
          reverse the result of comparisons
   -k, --key=POS1[,POS2]
          start a key at POS1 (origin 1), end it at POS2 (default end of line)

答え4

findの-printfを使用して単純化できます。

find . -type f -size +20k -printf "%h/%f: %kk\n" | sort -hrk 2,2

しかし、%sと%kの間の微妙さを理解するには、findのマンページを読んでください。 (/で検索を拒否し、テスト用にサイズを+20Mから+20kに減らしました。

関連情報