LoCでファイルを並べ替える - wc -lからパイプするときに並べ替えが機能しません。

LoCでファイルを並べ替える - wc -lからパイプするときに並べ替えが機能しません。

LoCでファイルディレクトリを並べ替えようとしています。

しかし、sortラインをパイプで接続すると何もしないようです。

paths=`find ./src/ | egrep "\.(cpp|h)$"`
for path in $paths; do
wc -l $path | sort -n;
done

結果は次のとおりです(予約注文でソートされますが、find数字wcは無視されます)。

50 /a/a.cpp
10 /a/a.h
200 /b/b.cpp
13 /b/b.h
...

パイプの代わりにファイルにソートを使用する場合:

for path in $paths; do
wc -l $path >> test.txt;
done

sort -n test.txt

それする働く:

```bash
10 /a/a.h
13 /b/b.h
50 /a/a.cpp
200 /b/b.cpp
...

パイプラインバージョンが機能しないのはなぜですか?

答え1

それぞれwcの出力を個別に、にsortパイプします。ループの出力全体を処理するためにパイプを移動すると、次のように動作します。

paths=`find ./src/ | egrep "\.(cpp|h)$"`
for path in $paths; do
wc -l $path
done | sort -n

find出力を繰り返さないでください。;また、フィルタリングされた出力egrepに使用する必要はありません。find以下を使用して上記のすべてのタスクを処理できます。

find ./src/ \( -name '*.cpp' -o -name '*.h' \) -exec wc -l {} \; | sort -n

または「全体」行があっても大丈夫ならより効率的に、

find ./src/ \( -name '*.cpp' -o -name '*.h' \) -exec wc -l {} + | sort -n

(ファイル名に改行文字が含まれていると、まだうまくいきません。)

答え2

最初のループは、wc -l各ループの単一ライン出力を個別に整列し、順番に出力します。動作しません(予想される結果です!)。

2番目のアプローチは、最初にwcすべての通話のすべての回線を集計してからソートします。これが正しいアプローチです。途中にファイルがあるかどうかはここでは問題ではありません。問題は、最初のループで実際に何もソートしないことです。

だから、

( for path in $paths; do
wc -l $path
done ) | sort -n

動作する必要があります。

find呼び出しはegrepを使用して出力をフィルタリングするため、奇妙です(たとえば、CMakeビルドで時々見つけることができるように、.cppで終わるフォルダと同じように興味深い結果につながります)。find -type f '(' -iname '*.cpp' -o -iname '*.h' ')'しかし、私はお勧めしません。find空白(非常に一般的です)、改行文字などを含むファイル名は、何らかの理由ですべて壊れる可能性があるため、ここですべて一緒に使用します。

代わりに、シェル(私の推測ではbash)が直接提供するものを使用してください。

shopt -s nullglob ## don't fail on empty globs
shopt -s globstar

for path in **/**.{h,cpp} ; do
  wc -l "${path}"
done | sort -n

実際に短くすることもできます。

shopt -s nullglob ## don't fail on empty globs
shopt -s globstar
wc -l **/*.{h,cpp} | sort -n

答え3

findwcそしてユーティリティのGNU実装は、headファイルパスに改行文字が含まれていないと仮定します。

{
  find . '(' -name '*.h' -o -name '*.cpp' ')' -print0
  printf '%s\0' /dev/null
} |
  wc -l --files0-from=- |
  head -n -2 | # remove up to 2 trailing lines to remove the /dev/null
               # and possibly "total" lines
  sort -n

-exec wc -l {} +「全体」行のみが出力されることを保証するこの方法とは対照的です。

複数のファイルが渡されると、1行だけ出力される問題がまだありますwctotalここでは、追加のコンテンツを追加し/dev/nullて最後に削除してこの問題を解決します。

関連情報