ディレクトリ内のテキストファイルの総行数を求めるには


はじめに結論ですが、

grep -rI '' foo|wc -l

がいいと思います。

次のようなスクリプトで作られるディレクトリで試しましょう。UbuntuのshのechoやBSD echo(Macの/bin/echo)ではなく、bashのechoを使ってください。

#!/bin/bash
rm -r foo
rm b
mkdir -p foo/bar
mkdir -p foo/.baz

echo -n 1 > foo/a
echo 2 > 'foo/b b'
echo 3 > foo/.c
echo -e '456\n\n\n\n8' > foo/bar/d
echo 9 > foo/.baz/e
echo -en '\x00' > foo/f
echo -en '\x00' > foo/g
echo -en '\x00' > foo/h
echo -en '\x00' > foo/i

上のスクリプトで作られるディレクトリfooには、テキストファイルが5つあり、行数の合計は9(空行を無視すると6)になります。

ディレクトリ内のテキストファイルの総行数を求める方法をネットで探すといろんな説が見つかりますが、一つずつ試してみましょう。(参考:ファイルの行数を数えるのは「wc -l file」ではありません

find foo -type f | xargs wc -l

結果は7(間違い。ファイル名に空白が含まれる場合に未対応)

find foo -type f -print0 | xargs -0 wc -l

結果は8(間違い。ファイルの末尾が改行でないいときに未対応)

find foo -type f -print0 | xargs -0 awk 'END{print NR}'

結果は13(間違い。バイナリファイルの処理が不適切)

grep -r . foo | wc -l

結果は10(間違い。バイナリファイルの処理が不適切)

grep -rI . foo | wc -l

結果は6(間違い。空行を無視するならこれでよい)

grep -rI '' foo | wc -l

結果は9(正解)

shopt -s dotglob; grep -rI '' foo/* | wc -l; shopt -u dotglob

結果は9(bash限定だが正解)

おまけ:特定のディレクトリを除外したいとき

mkdir -p foo/foo/.baz
echo 10 > foo/foo/.baz/10
mkdir foo/abaz
echo 11 > foo/abaz/11

.bazという名前のディレクトリをすべて除外したいときは、

grep -rI '' foo | grep -v '/\.baz/' | wc -l

比較的新しいgrepなら次のようにも書けます。

grep -rI '' --exclude-dir='\.baz' foo | wc -l

ディレクトリfoo/.bazだけを除外して、foo/foo/.bazは除外しないときは、

grep -rI '' foo | grep -v '^foo/\.baz/' | wc -l

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です