このコマンドを使用して、zipファイルでパターンを見つけます(ここで提案されているパターンと似ています)。 https://superuser.com/questions/144926/unix-grep-for-a-string-within-all-gzip-files-in-all-subdirectories
find . -regex ".*/.*zip" | xargs zgrep -m 1 -E "PATTERN"
初戦以降もグレッピングは続いた。たぶんfind
/xargs
犯人かもしれません。grep
最初の一致を見つけたら検索を停止するにはどうすればよいですか?
ポリスチレン最初の一致後にfindコマンドをどのように停止できますか?find
findの最初の一致だけでなく、成功した一致の後にgrepを停止する必要があるため、機能しません。
答え1
いくつか:
zgrep
圧縮アーカイブ内のファイルで.z
はなく圧縮ファイルを表示します。.gz
zip
zipgrep
アーカイブを表示するために時々unzip
一緒にバンドルされている(壊れた)スクリプトがありますが、このスクリプトzip
の機能はegrep
アーカイブのすべてのメンバーで実行されます(したがって、-m1
各メンバーはegrep
各ファイルの最初の発生を報告します)。zgrep
gzip
、各ファイルの出力を提供するスクリプトも同様です。ファイルを解凍できますが、アーカイブの最初のメンバーと圧縮されている場合にのみ可能です(ファイル内のすべてのメンバー、特に小さなメンバーを圧縮する必要はありません)。gzip -cdfq
grep
gzip -d
zip
zip
xargs
必要な数のコマンドを実行しますが、ファイルのリストが大きい場合は、複数のコマンドを実行できます。
ここで最良のオプションはzipgrep
手動で実装することです(ここではGNUツールを使用して)。
find . -name '*.zip' -type f -exec sh -c '
unzip -Z1 "$1" |
while IFS= read -r file; do
unzip -p "$1" "$file" | grep --label="$1//$file" -Hm1 -- "$0" && exit
done' PATTERN {} \; -quit
各ファイルはシェルを実行しますが、より多くのコマンドもzipgrep
実行します。zipgrep
アーカイブメンバーの名前にワイルドカード(*
、、、[
)などの文字(ASCII文字0x1〜0x1fなどのさまざまな文字)が含まれていると失敗することがありますが、これは?
主にSo badのバグと制限によるものです。unzip
zipgrep
答え2
努力する:
find . -iname '*.zip' -print0 | xargs -0r zgrep -l -E 'PATTERN'
-iname
私は代わりに使用しました-regex
。この方法もうまく機能し、私の考えでは、find
奇妙な正規表現処理よりも混乱しません。スペースまたはシェルメタ文字を含むファイル名を正しく処理するには、-print0
およびを使用します。xargs -0
grep
オプションは-l
マニュアルページに記載されています。
-l, --files-with-matches
Suppress normal output; instead print the name of each input
file from which output would normally have been printed. The
scanning will stop on the first match.
前述の最初の一致はファイルごとに行われるため、複数のファイルが一致するとすべて印刷されます。これは、一致するファイルが見つかった後でもgrepが他のファイルを検索し続けることを意味します。
最初の一致後に停止するには、grep
s--line-buffered
オプションを使用してgrepの出力をにパイプすることができますhead -1
。最初の一致が印刷されるとhead
印刷され、終了し、grep
標準出力がなくなり、終了してfind
従います。
find . -iname '*.zip' -print0 | xargs -0r zgrep --line-buffered -l -E 'PATTERN' | head -1
答え3
grep
(またはzgrep
)-m
オプションを使用すると読み取りが停止します。現在のファイル最初のゲームでは:
-m NUM, --max-count=NUM
Stop reading a file after NUM matching lines.
検索はブロックされません。Next文書。たとえば、
$ echo "hello" > foo
$ echo "hello" > bar
$ grep -m 1 hello foo bar
foo:hello
bar:hello
したがって、問題はxargs
複数のファイルを収集することではありません。最初の試合が終わった後に停止するためにgrep
(または)zgrep
文書、@Stephaneが提案したのと同じ小さなループを実行する必要があります。またはbashで同様のことをします。
shopt -s globstar
for i in **/*.zip; do
zgrep -l pattern "$i" && break;
done
またはzipアーカイブの場合複数のファイルが含まれています。(@Stephaneに感謝します):
shopt -s globstar
for i in **/*.zip; do
if unzip -p "$i" | grep -q hello; then
echo "$i" && break;
fi;
done
答え4
grep -m 1
各ファイルの最初の項目をリストします。
パイプを介して最初の一致を一覧表示する簡単な方法がありますhead -n 1
。まもなく検索になります信号パイプライン。
find . -regex ".*/.*zip" -print0 | xargs -0 zgrep -E "PATTERN" | head -n 1