2021年07月30日(金) [長年日記]
■ [howto][unix][shell] 行数カウント(2)
テキストファイル群の行数カウントについて復習。
- dir1とdir2配下の拡張子が.cppと.hのファイルの行数を数える
ものとする。
行数の合計だけわかればいい場合
以前にメモしている通り、findでファイルパス一覧を得てそれをcatでくっつけてwcへ渡せばできる。
$ find dir1 dir2 -type f -name '*.cpp' -o -name '*.h' | xargs cat | wc -l
ファイル毎の行数も知りたい場合
ファイルごとの行数を得るにはwcへファイルパス一覧を渡す必要がある。一覧はxargsで渡せるが、ファイル数が多いとwc呼び出しが複数回に分かれてしまい合計を得られなくなる。
wcには --files0-from というオプションがあり、これを使えばファイルパス一覧を標準入力から取得できてxargsが不要になってうまくいくようになる。--files0-from を使うためにfind側でも -print0 を指定する必要があって、そうするとファイルパターンの指定を括弧で囲う必要がでてきて少し不格好になる。
$ find dir1 dir2 -type f \( -name '*.cpp' -o -name '*.h' \) -print0 | wc -l --files0-from -
ファイルパターンの指定を簡潔に書くにはfindの -regex オプションを使い正規表現で書く手がある。ただ、デフォルトだと正規表現内に多量のエスケープが必要になり分かりにくくなるので、-regextype オプションで posix-egrep を指定した方がよさそう。
$ find dir1 dir2 -type f -regextype posix-egrep -regex '.*\.(cpp|h)' -print0 | wc -l --files0-from -