web-dev-qa-db-ja.com

すべてのサブディレクトリ内のすべてのgzipファイル内の文字列に対するUnixの「grep」

すべてのディレクトリとサブディレクトリにあるすべての.gzファイルを再帰的にgrepするにはどうすればよいですか?

8
matt123

@SteveWeetはもうすぐです。追加の引数として/ dev/nullを使用することは、ファイル名を強制的に表示するための優れた方法です(Steveに感謝します)が、見つかったすべてのファイルに対してexecを実行します-大きなオーバーヘッドです。

Zgrepをできるだけ数回実行して、各実行を最大限に活用したいとします。

find . -iname '*.gz' -print0 | xargs -0 zgrep PATTERN

xargsはzgrepにできるだけ多くの引数(ファイル名)を提供し、findコマンドによって提供されたすべてのファイルを使用するまで繰り返し実行します。 -print0および-0オプションを使用すると、ファイル名またはディレクトリ名のいずれかにスペースがある場合に機能します。

Mac OS Xでは、xargsなしで同じ効果を達成できます。

find . -iname '*.gz' -exec zgrep PATTERN {} +
13
Stephen P
$ zgrep --help
Usage: /bin/zgrep [OPTION]... [-e] PATTERN [FILE]...
Look for instances of PATTERN in the input FILEs, using their
uncompressed contents if they are compressed.

だから何かのような

find . -iname "*.gz" -exec zgrep PATTERN {} \
1
aioobe

@aioobeはもうすぐです。コマンドは仕事をしますが、ファイル名は教えてくれません

以下は、ファイル名も教えてくれるはずです。

find . -iname "*.gz" -exec zgrep PATTERN {} /dev/null \;

/dev/nullを追加すると、zgrepが2つのファイル名を認識できるようになるため、文字列が見つかった場合はファイルの名前が表示されます。

[〜#〜]編集[〜#〜]

さらなる調査により、私のマシン(OS/X)の場合、検索する-exec引数は、可能な限り多くのファイル名を追加することが明らかになりました(xargsの動作と同様)。

1
Steve Weet

以下はzshで扱います

for archive in **/*.gz; do
    echo "[${archive}] "
    gzip -dc ${archive} | grep -n "String"
done

bashkshなどでも機能する可能性があります。

0
Johnsyweb