이 명령을 사용하여 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.
검색이 차단되지는 않습니다.다음문서. 예를 들어:
$ 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