2009-05-14 12 views

risposta

264
  1. Tubazioni ad un altro processo (anche se questo non porterà a compimento ciò che hai detto che sta cercando di fare):

    command1 | command2 
    

    Questo invierà l'output di comando1 come input di comando2

  2. -exec su un find (questo farà ciò che si vogliono fare - ma è specifico per find)

    find . -name '*.foo' -exec cat {} \; 
    

    (Tutto tra find e -exec sono i predicati di ricerca che stavi già utilizzando. {} sostituirà il particolare file trovato nel comando (cat {} in questo caso); la \; è per terminare il comando -exec)

  3. uscita invio di un processo come argomenti della riga di comando a un altro processo

    command2 `command1` 
    

    ad esempio:.

    cat `find . -name '*.foo' -print` 
    

    (Nota questi sono BACK- QUOTE quotazioni non regolari (sotto la tilde ~ sulla mia tastiera).) Questo invierà l'output di command1 in command2 come argomenti della riga di comando. Si noti che i nomi dei file contenenti spazi (newline, ecc.) Saranno suddivisi in argomenti separati, però.

+2

cat' find -name' * .foo '-print' ha funzionato benissimo per me ... Grazie –

+0

I backquotes funzionano bene ed è più generalizzato, puoi usare questo per cat un elenco di file da un file pure. – Hazok

+11

Nota che le versioni moderne di 'find' ti permettono di scrivere:' find. -name '* .foo' -exec cat {} + ', dove' + 'indica che' find' dovrebbe raggruppare tutti i nomi di file come convenienti in una singola chiamata di comando. Questo è abbastanza utile (si occupa di spazi etc nei nomi di file senza ricorrere a '-print0' e' xargs -0'). –

6

Suona come un lavoro per uno script di shell per me:

for file in 'find -name *.xml' 
do 
    grep 'hello' file 
done 

o qualcosa di simile

+2

Questa è una risposta valida, sebbene non necessariamente ottimale, alla domanda. –

+1

... sì, ma è grandioso se vuoi un unico file con nomi di file elencati. –

+1

Mi piace il meglio. Un blocco circolare come questo lascia spazio per fare altre cose. – kakyo

62
find . -print | xargs grep something 

Se siete su Linux o avere GNU find e xargs, quindi utilizzare -print0 con find e -0 con xargs per gestire i nomi di file contenenti spazi e altri caratteri a palla dispari.

Se non si desidera che i nomi dei file, solo il testo, aggiungano un'opzione appropriata a grep (in genere -h per sopprimere le "intestazioni"). Per garantire assolutamente che il nome del file sia stampato da grep (anche se viene trovato un solo file, o l'ultima chiamata di grep ha solo un nome file), aggiungere /dev/null alla riga di comando xargs, in modo che ci sia sempre almeno due nomi di file.


Si noti che a POSIX 2008 Aggiunto il marcatore + a find il che significa che ora automaticamente gruppi come i file che sono ragionevoli in una singola esecuzione di comandi, molto simile xargs fa, ma con una serie di vantaggi:

  1. Non devi preoccuparti di caratteri dispari nei nomi dei file.
  2. Non devi preoccuparti che il comando venga invocato con nomi di file pari a zero.

Entrambi questi sono problemi con xargs senza l'opzione -0. Quindi, si potrebbe sensibilmente scrivere:

find . -exec grep something {} + 
+0

Per quelli confusi come sono, nota che in questo modo prima fornirai tutto l'output di find, e quindi fornirai l'output di 'xargs grep something'. –

+2

@EricHu: Vedo che sei confuso, ma non fa quello che dici, almeno non su qualsiasi sistema basato su Unix che io conosca. L'output di 'find' viene reindirizzato allo standard input di' xargs'. Il programma 'xargs' legge il suo input standard, dividendo l'input allo spazio bianco (spazi vuoti, newline, tabulazioni, ecc.) E aggiunge un numero di parole al comando' grep something' ed esegue la riga di comando. 'xargs' quindi continua a leggere l'input e ad eseguire i comandi finché non esaurisce l'input. 'xargs' esegue il comando' grep' ogni volta che è necessario per l'input che gli viene dato (da 'find' in questo esempio). –

+0

Ah mio errore, questo sta usando grep per cercare all'interno di ogni file abbinato.Stavo cercando semplicemente di filtrare l'output di find con grep –

2

Il comando find ha un argomento exec che è possibile utilizzare per cose come questa, si può solo fare il grep direttamente utilizzando tale.

Per esempio (from here, other good examples at this page):

find . -exec grep "www.athabasca" '{}' \; -print 
-1

Stai cercando di trovare il testo in file? Si può semplicemente utilizzare grep per questo ...

grep searchterm * 
30

Ci sono alcuni modi per passare l'elenco dei file restituiti dal comando find al comando cat, anche se tecnicamente non tutte le tubazioni uso, e nessuno in realtà il tubo direttamente a cat.

  1. Il più semplice è quello di utilizzare backticks:

    cat `find [whatever]` 
    

    modo equivalente, si può usare $() invece di backticks in alcune conchiglie, tra cui bash:

    cat $(find [whatever]) 
    

    Questo è meno portatile, ma è annidabile

    Entrambe le sintassi prendono l'uscita di find e la mettono sulla riga di comando di cat. Questo non funziona bene se lo find ha troppa uscita (più di quanto possa stare su una riga di comando) o se l'output ha caratteri speciali (come gli spazi).

  2. È possibile utilizzare -exec azione find s', che esegue un comando per ogni file che trova:

    find [whatever] -exec cat {} \; 
    

    Questo verrà eseguito cat una volta per ogni singolo file, piuttosto che l'esecuzione di una singola istanza di cat passarlo nomi di file multipli che possono essere inefficienti e che potrebbero non avere il comportamento desiderato per alcuni comandi (anche se va bene per cat). La sintassi è anche un po 'scomoda da digitare - è necessario sfuggire al punto e virgola perché la virgola è speciale per la shell!

    Alcune versioni di find (in particolare la versione GNU) consentono di sostituire ; con + usare find 's accodamento per eseguire un minor numero di casi di cat.

    find [whatever] -exec cat {} + 
    

    Ciò passerà più nomi di file per ogni chiamata cat, che può essere più efficiente. Si noti che è non garantito per l'utilizzo di una singola chiamata, tuttavia. Se la riga di comando è troppo lunga, gli argomenti vengono suddivisi tra più chiamate di cat. Per cat questo non è probabilmente un grosso problema, ma per alcuni altri comandi questo potrebbe cambiare il comportamento in modi indesiderati. Sui sistemi Linux, il limite di lunghezza della riga di comando è piuttosto ampio, quindi la suddivisione in più invocazioni è abbastanza rara rispetto ad altri sistemi operativi.

  3. L'approccio classico/portatile è quello di utilizzare xargs:

    find [whatever] | xargs cat 
    

    xargs eseguire il comando specificato (cat, in questo caso), e aggiunge gli argomenti in base a ciò che si legge da stdin. Proprio come -exec con +, questo interromperà la riga di comando se necessario. Cioè, se find produce troppa uscita, verrà eseguito più volte cat. Come accennato nella precedente sezione -exec, ci sono alcuni comandi in cui questa suddivisione può comportare un comportamento diverso. Si noti che l'utilizzo di xargs come questo ha problemi con spazi nei nomi di file, come xargs utilizza solo spazi bianchi come delimitatore.

  4. Il metodo più robusto, portatile ed efficiente utilizza anche xargs:

    find [whatever] -print0 | xargs -0 cat 
    

    La bandiera -print0 dice find utilizzare \0 delimitatori (carattere nullo) tra i nomi di file, e la bandiera -0 dice xargs aspettarsi questi Delimitatori \0. Ciò ha praticamente un comportamento identico all'approccio -exec ... +, sebbene sia più portatile (ma sfortunatamente più dettagliato).

-1

Per elencare e vedere i contenuti di tutti i file abc.def su un server nella directory/ghi e/jkl

find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \; 

Per elencare i file abc.def che hanno commentato le voci e Display Vedere le annotazioni del directory/ghi e/jkl

find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \; 
1

in bash, i seguenti sarebbe opportuno:

find /dir -type f -print0 | xargs -0i cat {} | grep whatever 

Questo troverà tutti i file nella directory /dir e condurrà in modo sicuro i nomi dei file in xargs, che guiderà in modo sicuro grep.

Saltare xargs non è una buona idea se si dispone di molte migliaia di file in /dir; cat si interromperà a causa dell'eccessiva lunghezza dell'elenco di argomenti. xargs risolverà tutto ciò per te.

L'argomento -print0 di find ingrana con la -0 argomento xargs per gestire nomi di file con spazi correttamente. L'argomento -i su xargs consente di inserire il nome file dove richiesto nella riga di comando cat. Le parentesi sono sostituite dal nome del file convogliato nel comando cat da find.

2

Ecco il mio colpo per uso generale:

grep YOURSTRING `find .` 

sarà stampare il nome del file

0

Questo funziona per me

find _CACHE_* | while read line; do 
    cat "$line" | grep "something" 
done 
9

per raggiungere questo obiettivo (usando bash) lo farei come segue:

cat $(find . -name '*.foo') 

Questa è conosciuta come la "sostituzione di comando" e toglie di default il feed di riga, il che è davvero conveniente! più

informazioni here

0

Utilizzare ggrep.

ggrep -H -R -I "mysearchstring" * 

per cercare un file in UNIX testo che contiene si trova nella directory corrente o in una sottodirectory

4

Ecco il mio modo per trovare i nomi di file che contengono alcuni contenuti che mi interessa, un solo bash linea che gestisce bene gli spazi nei nomi dei file troppo:

find . -name \*.xml | while read i; do grep '<?xml' "$i" >/dev/null; [ $? == 0 ] && echo $i; done 
1

io uso qualcosa di simile:

find . -name <filename> -print0 | xargs -0 cat | grep <word2search4> 

"-print0" l'argomento per "trova" e "-0" argomento per "xargs" sono necessari per gestire correttamente gli spazi nei percorsi/nomi di file.

Problemi correlati