Sto facendo un finde quindi ottenere un elenco di file. Come posso collegarlo a un'altra utility come cat(in modo che cat mostri il contenuto di tutti quei file) e fondamentalmente abbia bisogno di grepqualcosa da questi file.
Sto facendo un finde quindi ottenere un elenco di file. Come posso collegarlo a un'altra utility come cat(in modo che cat mostri il contenuto di tutti quei file) e fondamentalmente abbia bisogno di grepqualcosa da questi file.
Risposte:
Piping su un altro processo (anche se questo NON riuscirà a realizzare ciò che hai detto che stai cercando di fare):
command1 | command2
Questo invierà l'output di command1 come input di command2
-execsu un find(questo farà quello che vuoi fare - ma è specifico per find)
find . -name '*.foo' -exec cat {} \;
(Tutto tra finde -execsono i predicati find che stavi già utilizzando. {}Sostituirà il particolare file che hai trovato nel comando ( cat {}in questo caso); \;è quello di terminare il -execcomando.)
invia l'output di un processo come argomento della riga di comando a un altro processo
command2 `command1`
per esempio:
cat `find . -name '*.foo' -print`
(Nota che questi sono BACK-QUOTES non virgolette regolari (sotto la tilde ~ sulla mia tastiera).) Questo invierà l'output di command1in command2come argomenti della riga di comando. Tuttavia, i nomi dei file contenenti spazi (newline, ecc.) Verranno suddivisi in argomenti separati.
findconsentono di scrivere:, find . -name '*.foo' -exec cat {} +dove +indica che finddovrebbero raggruppare tutti i nomi di file più convenienti in un'unica chiamata di comando. Questo è abbastanza utile (si occupa di spazi ecc. Nei nomi dei file senza ricorrere a -print0e xargs -0).
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008 ha aggiunto il +marcatore a findcui ora raggruppa automaticamente tutti i file ragionevoli in un'unica esecuzione di comando, proprio come xargsfa, ma con una serie di vantaggi:
Il problema del nome file è un problema con xargssenza l' -0opzione e il problema "esegui anche con zero nomi file" è un problema con o senza l' -0opzione - ma GNU xargsha il -ro--no-run-if-empty opzione per impedire che ciò accada. Inoltre, questa notazione riduce il numero di processi, non che tu possa misurare la differenza nelle prestazioni. Quindi, potresti scrivere sensatamente:
find . -exec grep something {} +
find . -print | xargs grep something
Se sei su Linux o hai GNU finde xargscomandi, usa -print0con finde -0conxargs per gestire i nomi dei file contenenti spazi e altri caratteri dispari.
find . -print0 | xargs -0 grep something
grepSe non desideri i nomi dei file (solo il testo), aggiungi un'opzione appropriata a grep(di solito -hper sopprimere le "intestazioni"). Per garantire assolutamente che il nome del file sia stampato da grep(anche se viene trovato un solo file o all'ultima chiamata di grepviene assegnato solo 1 nome file), quindi aggiungere/dev/null alla xargsriga di comando, in modo che ci siano sempre almeno due nomi di file.
xargs grep something.
findviene reindirizzato all'input standard di xargs. Il xargsprogramma legge l'input standard, suddividendo l'input su uno spazio bianco (spazi vuoti, newline, tab, ecc.) E aggiunge un numero di parole al comando grep somethinged esegue la riga di comando. xargsquindi continua a leggere l'input e ad eseguire i comandi finché non si esaurisce l'input. xargsesegue il grepcomando tutte le volte che è necessario per l'input fornito (da findquesto esempio).
/dev/nullperdere i messaggi di errore.
Esistono alcuni modi per passare l'elenco dei file restituiti dal findcomando al catcomando, sebbene tecnicamente non tutti utilizzino il piping e nessuno effettivamente esegua il pipe direttamente cat.
Il più semplice è usare i backtick ( `):
cat `find [whatever]`
Questo prende l'output di finde lo posiziona efficacemente sulla riga di comando di cat. Questo non funziona bene se findha un output eccessivo (più di quello che può stare su una riga di comando) o se l'output ha caratteri speciali (come gli spazi).
In alcune shell, incluso bash, si possono usare al $()posto dei backtick:
cat $(find [whatever])
Questo è meno portatile, ma è annidabile. A parte questo, ha praticamente le stesse avvertenze dei backtick.
Poiché l'esecuzione di altri comandi su ciò che è stato trovato è un uso comune per find, find ha -execun'azione che esegue un comando per ogni file che trova:
find [whatever] -exec cat {} \;
Il {}è un segnaposto per il nome del file, e le \;segna la fine del comando (è possibile avere altre azioni dopo -exec.)
Questo verrà eseguito catuna volta per ogni singolo file anziché eseguire una singola istanza di catpassare più nomi di file che può essere inefficiente e potrebbe non avere il comportamento desiderato per alcuni comandi (anche se va bene cat). Anche la sintassi è una cosa scomoda da digitare: è necessario sfuggire al punto e virgola perché il punto e virgola è speciale per la shell!
Alcune versioni di find(in particolare la versione GNU) consentono di sostituire ;con +un uso -exec'accodamento s per eseguire un minor numero di casi di cat:
find [whatever] -exec cat {} +
Questo passerà più nomi di file a ogni invocazione di cat, che può essere più efficiente.
Si noti che ciò non garantisce l'utilizzo di una singola chiamata. Se la riga di comando fosse troppo lunga, gli argomenti vengono suddivisi su più invocazioni di cat. Per catquesto probabilmente non è un grosso problema, ma per alcuni altri comandi questo può cambiare il comportamento in modi indesiderati. Sui sistemi Linux, il limite di lunghezza della riga di comando è piuttosto elevato, quindi la suddivisione in più invocazioni è piuttosto rara rispetto ad altri sistemi operativi.
L'approccio classico / portatile consiste nell'utilizzare xargs:
find [whatever] | xargs cat
xargsesegue il comando specificato ( cat, in questo caso) e aggiunge argomenti in base a ciò che legge da stdin. Proprio come -execcon +, questo interromperà la riga di comando, se necessario. Cioè, se findproduce troppo output, verrà eseguito catpiù volte. Come menzionato nella sezione -execprecedente, ci sono alcuni comandi in cui questa suddivisione può comportare comportamenti diversi. Si noti che l'utilizzo in xargsquesto modo ha problemi con gli spazi nei nomi dei file, in quanto xargsutilizza solo gli spazi bianchi come delimitatore.
Il metodo più robusto, portatile ed efficiente utilizza anche xargs:
find [whatever] -print0 | xargs -0 cat
Il -print0flag dice finddi usare \0delimitatori (carattere null) tra i nomi di file e il -0flag dice xargsdi aspettarsi questi \0delimitatori. Questo ha un comportamento praticamente identico all'approccio -exec... +, sebbene sia più portatile (ma sfortunatamente più prolisso).
ls.
$()Funziona anche con comandi diversi da find .
Mi sembra un lavoro per uno script di shell:
for file in 'find -name *.xml'
do
grep 'hello' file
done
o qualcosa di simile
Il comando find ha un argomento -exec che puoi usare per cose come questa, puoi semplicemente fare il grep direttamente usando quello.
Ad esempio ( da qui, altri buoni esempi in questa pagina ):
find . -exec grep "www.athabasca" '{}' \; -print
In bash, sarebbe appropriato:
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
Questo troverà tutti i file nella /dirdirectory e inoltrerà in modo sicuro i nomi dei file xargs, che guideranno in sicurezzagrep .
Saltare xargsnon è una buona idea se hai molte migliaia di file /dir; catsi interromperà a causa dell'eccessiva lunghezza dell'elenco degli argomenti.xargsrisolverà tutto per te.
L' -print0argomento da findassociare -0all'argomento xargsper gestire correttamente i nomi di file con spazi. L' -iargomento per xargsconsentire di inserire il nome file dove richiesto nella catriga di comando. Le parentesi vengono sostituite dal nome file reindirizzato nel catcomando da find.
Questo funziona per me
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
Usa ggrep .
ggrep -H -R -I "mysearchstring" *
per cercare un file in unix contenente testo situato nella directory corrente o in una sottodirectory
Questo stamperà ricorsivamente il nome e il contenuto dei soli file.
find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Modifica (versione migliorata): questo stamperà ricorsivamente il nome e il contenuto dei file di testo (ascii).
find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'
Un altro tentativo
find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;
Stai cercando di trovare testo nei file? Puoi semplicemente usare grep per quello ...
grep searchterm *
Per elencare e vedere i contenuti di tutti i file abc.def su un server nelle 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 voci commentate e visualizzate, vedere quelle voci nelle directory / ghi e / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
find -name '*.foo' -printfunzionato benissimo per me ... Grazie