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
に直接パイプされるため、一度にメモリに保存されるのはファイルの少量のコンテンツだけです。 cat
の1回の呼び出しに対してファイルが多すぎる場合、cat
は複数回呼び出されますが、すべての出力は単一のwc
プロセスにパイプされます。
単一のcat
インスタンスを介してすべてのファイルをwc
して、行の総数を取得できます。
find . -name '*.m' -exec cat {} \; | wc -l
現代ではGNUプラットフォームwcとfindの-print0と-files0-fromのパラメータを組み合わせて、ファイルの行を最後に合計して数えるコマンドに組み合わせることができます。例:
find . -name '*.c' -type f -print0 | wc -l --files0-from=-
wcの代わりにsedを使用して行を数えることもできます。
find . -name '*.m' -exec sed -n '$=' {} \;
どこ '$='
は、行数を保持する「特殊変数」です
編集
sloccount のようなものを試すこともできます
うーん、catを使用したソリューションは、ファイルが多い場合、特に大きなファイルの場合に問題が発生する可能性があります。
私がテストしたように、2番目の解決策は、ファイルごとの行数だけではなく、合計を与えません。
私はこのようなものを好むでしょう:
find . -name '*.m' | xargs wc -l | tail -1
これにより、ファイルの数とサイズに関係なく、処理が速くなります。
sedはカウントに適したツールではありません。代わりにawkを使用してください:
find . -name '*.m' -exec awk '{print NR}' {} +
\の代わりに+を使用します。 (xargsの場合と同様に)見つかったN個のファイルごとに強制的にawkを呼び出します。
大きなディレクトリの場合は、次を使用する必要があります。
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}'