2009-08-10 10 views
40

Mój obecny problem polega na tym, że mam około 10 folderów, które zawierają spakowane pliki gzip (średnio po 5 sztuk). Dzięki temu można otwierać i przeglądać 50 plików.znajdź ciąg wewnątrz spakowanego pliku gzip w folderze

Czy istnieje prostsza metoda sprawdzenia, czy zagnieżdżony plik wewnątrz folderu ma określony wzorzec, czy nie?

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

Zamiast pisać skrypt, czy mogę zrobić to samo w jednym wierszu dla wszystkich folderów i podfolderów?

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

Odpowiedz

47

zgrep będzie wyglądać w plikach spakowane gzipem, posiada opcję -R rekurencyjne, a -H pokazać mi opcję Nazwa pliku:

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

FWIW, mój zgrep nie obsługuje -R – ZombieDev

+0

@Ned Batchelder, Dzięki za podanie kierunku. Ale dla mnie następujące działające opcje zgrep "pliki" wzór – hiren

+0

'zgrep -R --include = \ *. Gz -H" wzór "' na zsh – blacktooth

7

użyć polecenia find

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

lub spróbuj użyć opcji rekurencyjnego (-R) z zcat

+0

-bash-3.00 $ find. -name "* .gz" -exec zcat "{}" + | grep "NOT OK" find: brakujący argument do '-exec ' coś wydaje się być brakujące po exec? – gagneet

+0

to działa dla mnie. – ghostdog74

+0

może spróbuj zmienić, aby znaleźć ... +; | grep ... i zobacz – ghostdog74

18

Nie trzeba zcat tutaj, bo nie ma zgrep i zegrep.

Jeśli chcesz uruchomić komendę nad hierarchii katalogów, należy użyć znalezisko:

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

a także „ls *.gz” jest bezużyteczny w dla i należy po prostu użyć „* .gz " w przyszłości.

+0

Otrzymuję linie, które zawierają ten wzorzec, ale nie nazwę pliku tą metodą. Czy jest jakiś sposób, aby to również wymienione? – gagneet

+2

'znaleźć. -name '* .gz' -print0 | xargs -0 zgrep pattern'? – Hasturkun

+2

Stara sztuczka grep: znajdź. -name "* .gz" -exec zgrep ⟨pattern⟩/dev/null \ {\} \; # Sprawi to, że grep pomyśli, że istnieje więcej niż jeden plik i wypisze nazwę pliku. –

6

jak zgrep nie obsługują -R

myślę roztwór „Nietzschego-Jou” może być lepszy odpowiedź, ale chciałbym dodać -h opcja pokazywania nazwy pliku coś takiego

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

Dzięki za polecenie pokazania nazwy pliku :) –

6

w najbliższych trochę późno na to, miał podobny problem i był w stanie r esolve za pomocą;

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

Jak szczegółowo tutaj;

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

to jednak nie zobaczyć oryginalny plik, który wynika z dopasowaną, zamiast wykazujące „(standardowe wejście)”, jak to idzie z rury. zcat nie obsługuje również wypisywania nazwy.

Pod względem wydajności, to właśnie otrzymaliśmy;

$ 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 

Jak widać, przy użyciu metody find|zcat jest znacznie wolniejsze niż przy użyciu zcat -r gdy ma do czynienia z nawet niewielkiej ilości plików. Nie mogłem również wytworzyć zcat nazwy pliku (użycie nazwy -v spowoduje wyświetlenie nazwy pliku, ale nie w każdym wierszu). Wydaje się, że obecnie nie ma narzędzia, które zapewni zarówno szybkość, jak i spójność nazwy z grep (tj. Opcja -H).

Jeśli chcesz zidentyfikować nazwę pliku, do którego należy wynik, musisz napisać własne narzędzie (można zrobić w 50 wierszach kodu Pythona) lub użyć wolniejszej metody. Jeśli nie musisz identyfikować nazwy, użyj zcat -r.

Nadzieja to pomaga

2

find . -name "*.gz"|xargs zcat | grep "pattern" powinien robić.