Supponiamo che io voglia trovare tutti i file .txt e cercare qualche stringa. Farei:

find ./ -type f -name "*.txt" -exec egrep -iH "something" "{}" \; 

E se volessi applicare un filtro più complesso, come questo:

egrep something file.txt | egrep somethingelse | egrep other 

Allinterno di find -exec? (o simile)

Tieni presente che sto cercando una soluzione che potrei facilmente digitare quando ne ho bisogno. So che questo potrebbe essere fatto con poche righe usando uno script di shell, ma non è quello che sto cercando.

Risposta

Se devi farlo da find, devi chiamare una shell:

find ./ -type f -name "*.txt" -exec sh -c "grep -EiH something "$1" | grep -E somethingelse | grep -E other" sh {} \; 

Altre alternative includono lutilizzo di xargs:

find ./ -type f -name "*.txt" | xargs -I{} grep -EiH something {} | grep -EiH somethingelse | grep -EiH other 

Oppure , molto più sicuro per nomi di file arbitrari (supponendo che find supporti -print0):

find ./ -type f -name "*.txt" -print0 | xargs -0 grep -EiH something {} | grep -Ei somethingelse | grep -Ei other 

In alternativa, potresti semplicemente utilizzare un ciclo di shell:

find ./ -type f -name "*.txt" -print0 | while IFS= read -d "" file; do grep -Ei something "$file" | grep -Ei somethingelse | grep -Ei other done 

Commenti

  • Il primo è esattamente quello che stavo cercando. Estremamente semplice e abbastanza piccolo da poter essere digitato a seconda delle mie esigenze. Grazie.
  • … e xargs potrebbe anche essere usato come xargs -I {} sh -c '...' sh {}, se si vuole (fa è possibile eseguire lavori paralleli con -P se si desidera).

Risposta

Modifica: questa risposta non è preferita , ma viene lasciata qui per confronto e illustrazione di insidie potenzialmente pericolose nello scripting bash.


Puoi inserire bash (o unaltra shell) come comando -exec:

 find -type -f -name "*.txt" -exec bash -c "egrep -iH something "{}" | egrep somethingelse | egrep other" \;  

Uno degli svantaggi di farlo in questo modo è che crea più potenziale per problemi di quotazione annidata man mano che i comandi diventano più complessi. Se vuoi evitarlo, puoi suddividerlo in un for -loop:

 for i in $(find -type -f -name "*.txt"); do if egrep -iH something "$i" | egrep somethingelse | egrep other; then echo "Found something: $i" fi done  

Commenti

  • Il primo è esattamente quello che stavo cercando. Estremamente semplice e abbastanza piccolo da poter essere digitato a seconda delle mie esigenze. Grazie.
  • Quel for loop è una pessima idea. Noto anche come bash trabocchetto # 1 .
  • Questo "{}" nel tuo primo comando può persino portare alliniezione di codice. Immagina di aver ricevuto file da me e ' è un file chiamato letteralmente " & rm -rf ~ & : ".txt. Fortunatamente per te -type -f non è valido, ha solo salvato la tua directory home. Correggi lerrore di battitura e riprova. 🙂 terdon ha fatto bene: find … -exec sh -c '… "$1" …' foo {} \;.
  • Grazie per le informazioni! Sì, -type -f è un errore di battitura che faccio costantemente quando utilizzo find e non ' non lo nota nella mia risposta. Ops. La risposta di terdon ' è migliore, ma ' la lascio a fini comparativi.
  • @terdon: tx per fare riferimento alla pagina mywiki.wooledge.org. ' è bello avere un gruppo di medici di famiglia riassunti in modo ordinato in un unico posto.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *