Posted at

複数ファイルをファイル単位にgrepでフィルタしてwcで行数を数える

ただ合計を数えるだけではなくて、ヒストグラムを作りたいときとか、各ファイルの行数を数えたい場合で、かつ、grepでフィルタもしたいとき。たとえば、特定のIPアドレスを除外してアクセスログの行数を数えるとか。

$ find . | xargs wc

すぐに思いつくのはこれです。これでファイルごとの行数が数えられますが、grep条件は加味されていない数値です。

$ find . | xargs grep -v 'xxx' | wc

これにgrepをつけると、フィルタ条件を満たすのですが、数値は合計だけになってしまい、ファイルごとの数値がわかりません。

両立させる方法はこんな感じです。

$ find . | xargs -n 1 sh -c 'echo -n $0; grep -v "xxx" $0 | wc'

xargsの出力をいったんShellに渡すことで、複数のコマンドを並列できるようになります。前半でファイル名を表示して、後半で集計しています。

xargsのnオプションでの1指定は、入力を1個ずつ渡すって宣言です。渡されたものはShellなので$0とかで受け取ります。-I{}でも同じことができます。

echoのnオプションは改行しないってものです。