Unix 'grep' per una stringa all'interno di tutti i file gzip in tutte le sottodirectory


8

Come posso richiedere una stringa in modo ricorsivo attraverso tutti i .gzfile in tutte le directory e sottodirectory?

Risposte:


13

@Steve Weet è quasi arrivato. L'uso di / dev / null come argomento aggiuntivo è un buon modo per forzare la visualizzazione del nome del file (lo ricorderò, grazie Steve) ma esegue comunque il exec per ogni file trovato - un enorme sovraccarico.

Volete eseguire zgrep il minor numero di volte possibile, ottenendo il massimo da ogni esecuzione:

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

xargsfornirà il maggior numero possibile di arg (nomi di file) a zgrep e lo eseguirà ripetutamente fino a quando non avrà utilizzato tutti i file forniti dal findcomando. L'uso delle opzioni -print0e gli -0consente di funzionare se ci sono spazi in uno dei nomi di file o directory.

Su Mac OS X, puoi ottenere lo stesso effetto senza xargs:

find . -iname '*.gz' -exec zgrep PATTERN {} +

+1 È davvero bello. Non mi ero reso conto che gli xargs avessero superato più di un argomento. Gran parte del mio * nix command-fu ha 20 anni e non credo che xargs lo abbia fatto 20 anni fa.
Steve Weet,

Si scopre che find su os / x si comporta allo stesso modo di xargs
Steve Weet,

1
Vedi il mio commento alla risposta di Steve Weet riguardo al finale "+" a -exec.
Daniel Andersson,

Usare -Hper mostrare sempre il nome del file con la riga corrispondente, almeno in GNU grep.
Daniel Andersson,

1
$ 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.

Quindi qualcosa del genere

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

-Exec genererà una nuova istanza di zgrep per ogni file su cui scorre per impedirti di vedere il nome del file. Sarebbe meglio usare zgrep -rper attraversare un albero o se il -r non funziona, xargs zgrep
convoglia

Salgo /bin/zgrep: -r: option not supportedsul mio sistema Ubuntu appena installato.
aioobe,

Puoi usare xargsinvece invece.
Noufal Ibrahim,

Vedi il mio commento alla risposta di Steve Weet riguardo al finale "+" a -exec.
Daniel Andersson,

1

@aioobe è quasi arrivato. Il comando farà il lavoro ma non ti dirà il nome del file

Quanto segue dovrebbe indicare anche il nome del file:

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

L'aggiunta di /dev/nullassicurerà che zgrep veda due nomi di file, quindi ti mostrerà il nome del file se trova la stringa

MODIFICARE

Ulteriori ricerche rivelano che per la mia macchina (OS / X) l' -execargomento da trovare aggiungerà quanti più nomi di file possibili (simile al modo in cui xargssi comporta).


È piuttosto bello, non lo sapevo sull'OSX -exec: mi occupo della portabilità, quindi non lo userei in uno script, ma ottimo per il prompt dei comandi.

Per altre versioni di find, usare '+' invece di '\;' per terminare l'istruzione exec farà lo stesso di OSX, secondo le storie in questo thread, per impostazione predefinita. Vedere la voce manuale per '-exec command {} +'. Non è vero per tutte le versioni di find, ma per la maggior parte di quelle moderne (ad esempio nelle distribuzioni basate su Debian).
Daniel Andersson,

Usare -Hper mostrare sempre il nome del file con la riga corrispondente, almeno in GNU grep, anziché l' /dev/nullhack.
Daniel Andersson,

0

Quanto segue funziona a meraviglia zsh

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

Può anche funzionare in bash, kshecc ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.