2009-08-10 27 views
40

Vấn đề hiện tại của tôi là tôi có khoảng 10 thư mục chứa các tệp được nén (khoảng trung bình 5 tệp). Điều này làm cho nó 50 tập tin để mở và nhìn vào.tìm chuỗi bên trong tệp được nén trong một thư mục

Có phương pháp đơn giản hơn để tìm hiểu xem tệp gzipped trong thư mục có mẫu cụ thể hay không?

zcat ABC/myzippedfile1.txt.gz | grep "pattern match" 
zcat ABC/myzippedfile2.txt.gz | grep "pattern match" 

Thay vì viết kịch bản, tôi có thể làm tương tự trong một dòng, cho tất cả thư mục và thư mục con không?

for f in `ls *.gz`; do echo $f; zcat $f | grep <pattern>; done; 

Trả lời

47

zgrep sẽ tìm trong các file đã giải nén, có một lựa chọn đệ quy -R và -H chỉ cho tôi tùy chọn filename:

zgrep -R --include=*.gz -H "pattern match" . 
+12

FWIW, zgrep của tôi không hỗ trợ -R – ZombieDev

+0

@Ned Batchelder, Cảm ơn đã đưa ra một hướng. Nhưng đối với tôi sau đây làm việc zgrep tùy chọn "mẫu" tập tin – hiren

+0

'zgrep -R --include = \ *. Gz -H" mẫu "' trên zsh – blacktooth

7

sử dụng find lệnh

find . -name "*.gz" -exec zcat "{}" + |grep "test" 

hoặc thử sử dụng tùy chọn đệ quy (-r) của zcat

+0

-bash-3.00 $ find. -name "* .gz" -exec zcat "{}" + | grep "NOT OK" tìm: thiếu đối số cho '-exec ' một cái gì đó dường như bị thiếu sau khi exec? – gagneet

+0

nó hoạt động cho tôi. – ghostdog74

+0

có thể thử thay đổi để tìm ... +; | grep ... và xem – ghostdog74

18

Bạn không cần zcat ở đây vì không zgrepzegrep.

Nếu bạn muốn chạy một lệnh trên một hệ thống phân cấp thư mục, bạn sử dụng tìm:

find . -name "*.gz" -exec zgrep ⟨pattern⟩ \{\} \; 

Và cũng “ls *.gz” là vô ích trong cho và bạn chỉ nên sử dụng “* gz " trong tương lai.

+0

Tôi nhận được các dòng có chứa mẫu này, nhưng không phải là tên của tệp theo phương pháp này. Có cách nào để có được điều đó cũng được liệt kê? – gagneet

+2

'tìm. -name '* .gz' -print0 | xargs -0 zgrep pattern'? – Hasturkun

+2

Old grep trick: tìm. -name "* .gz" -exec zgrep ⟨pattern⟩/dev/null \ {\} \; # Điều đó sẽ làm cho grep nghĩ rằng có nhiều hơn một tệp duy nhất và in tên tệp. –

6

cách zgrep không hỗ trợ -R

Tôi nghĩ rằng giải pháp của "Nietzsche-jou" có thể là một câu trả lời tốt hơn, nhưng tôi sẽ thêm tùy chọn -H để hiển thị tên tập tin một cái gì đó như thế này

find . -name "*.gz" -exec zgrep -H 'PATTERN' \{\} \; 
+0

Cảm ơn lệnh để hiển thị tên của tệp :) –

6

Sắp tới trong một hơi muộn về điều này, có một vấn đề tương tự và đã có thể r sử dụng;

zcat -r /some/dir/here | grep "blah" 

Được nêu chi tiết tại đây;

http://manpages.ubuntu.com/manpages/quantal/man1/gzip.1.html

Tuy nhiên, điều này không hiển thị các tập tin ban đầu mà kết quả phù hợp từ, thay vì hiển thị "(standard input)" như nó đến từ một đường ống. zcat dường như không hỗ trợ xuất một tên hoặc.

Xét về hiệu suất, đây là những gì chúng tôi có;

$ alias dropcache="sync && echo 3 > /proc/sys/vm/drop_caches" 

$ find 09/01 | wc -l 
4208 

$ du -chs 09/01 
24M 

$ dropcache; time zcat -r 09/01 > /dev/null 
real 0m3.561s 

$ dropcache; time find 09/01 -iname '*.txt.gz' -exec zcat '{}' \; > /dev/null 
0m38.041s 

Như bạn thấy, sử dụng phương pháp find|zcat là chậm hơn so với sử dụng zcat -r khi giao dịch với ngay cả một khối lượng nhỏ các tập tin đáng kể. Tôi cũng không thể tạo đầu ra zcat tên tệp (sử dụng -v dường như sẽ xuất tên tệp, nhưng không xuất hiện trên mỗi dòng đơn). Có vẻ như hiện tại không có công cụ nào cung cấp cả tính nhất quán về tốc độ và tên với grep (tức là tùy chọn -H).

Nếu bạn cần xác định tên của tệp mà kết quả thuộc về, thì bạn sẽ cần phải viết công cụ của riêng bạn (có thể được thực hiện trong 50 dòng mã Python) hoặc sử dụng phương thức chậm hơn. Nếu bạn không cần phải xác định tên, hãy sử dụng zcat -r.

Hy vọng điều này sẽ giúp

2

find . -name "*.gz"|xargs zcat | grep "pattern" nên làm.

Các vấn đề liên quan