私はsedを使用して、特定の拡張子に基づいてすべての行をカウントしようとしていました。
find -name '*.m' -exec wc -l {} \; | sed ...
私は次のことをしようとしていましたが、合計を取得するためにこの特定の行にsedをどのように含めるのでしょうか。
また、wcから:を使用して適切なフォーマットを取得することもできます。
wc `find -name '*.m'`
ここでの回答のほとんどは、多数のファイルではうまく機能しません。ファイル名のリストが1回のコマンドライン呼び出しに対して長すぎる場合に破損するものもあれば、-exec
すべてのファイルに対して新しいプロセスを開始するために非効率的なものもあります。堅牢で効率的なソリューションは次のようになると思います。
find . -type f -name "*.m" -print0 | xargs -0 cat | wc -l
この方法を使用cat
すると、出力が直接パイプされwc
、ファイルのコンテンツのごく一部のみが一度にメモリに保持されるため、問題ありません。の1回の呼び出しに対してファイルが多すぎる場合、cat
はcat
複数回呼び出されますが、すべての出力は引き続き1つのwc
プロセスにパイプされます。
cat
1つのインスタンスですべてのファイルwc
を取得して、行の総数を取得できます。
find . -name '*.m' -exec cat {} \; | wc -l
最新のGNUプラットフォームでは、wcおよびfind take -print0および-files0-fromパラメーターを組み合わせて、ファイル内の行を最後に合計でカウントするコマンドにすることができます。例:
find . -name '*.c' -type f -print0 | wc -l --files0-from=-
wcの代わりに行を数えるためにsedを使用することもできます。
find . -name '*.m' -exec sed -n '$=' {} \;
ここ'$='
で、は行数を保持する「特別な変数」です
編集
sloccountのようなものを試すこともできます
うーん、特に大きなファイルがたくさんある場合、猫を使った解決策は問題になるかもしれません。
私がテストしたように、2番目の解決策は合計ではなく、ファイルごとの行数だけを示します。
私はこのようなものを好みます:
find . -name '*.m' | xargs wc -l | tail -1
これにより、ファイルの数やサイズに関係なく、作業が高速になります。
大きなディレクトリの場合は、次を使用する必要があります。
find . -type f -name '*.m' -exec sed -n '$=' '{}' + 2>/dev/null | awk '{ total+=$1 }END{print total}'
# alternative using awk twice
find . -type f -name '*.m' -exec awk 'END {print NR}' '{}' + 2>/dev/null | awk '{ total+=$1 }END{print total}'
sedはカウントに適したツールではありません。代わりにawkを使用してください:
find . -name '*.m' -exec awk '{print NR}' {} +
\の代わりに+を使用する; (xargsのように)見つかったN個のファイルごとにawkを呼び出すように強制します。