Beter uit te leggen aan de hand van voorbeelden.

Ik kan:

find . -name "*.py" -type f > output.txt 

Maar hoe kan ik de uitvoer in hetzelfde bestand opslaan voor:

find . -name "*.py" -type f -exec grep "something" {} \ 

Ik kan “niet gewoon doen

find . -name "*.py" -type f -exec grep "something" {} \ > output.txt 

Answer

Als ik je goed begrijp, is dit wat je wilt doen:

find . -name "*.py" -print0 | xargs -0 grep "something" > output.txt 

Vind alle bestanden met de extensie .py, grep alleen rijen die something en sla de rijen op in output.txt. Als het output.txt -bestand bestaat, wordt het afgekapt, anders zal worden gemaakt.

Met -exec:

find . -name "*.py" -exec grep "something" {} \; > output.txt 

Ik neem Chris Downs op geef hier commentaar: Het bovenstaande commando zal ertoe leiden dat grep net zo vaak wordt uitgevoerd als find padnamen vindt die de gegeven tests doorstaan (alleen de enkele test hierboven). Als u echter \; vervangt door een +, wordt grep aangeroepen met meerdere padnamen van find (tot een bepaalde limiet).

Zie vraag Puntkomma (;) versus plus ( +) met exec in find voor meer informatie over het onderwerp.

Reacties

  • Gebruik + in plaats van \;, zal het de uitvoeringstijd aanzienlijk verbeteren (aangezien het argumenten voorafgaand aan de uitvoering zal doorgeven tot ARG_MAX).
  • Nu begrijp ik de kracht van xargs! Bedankt!
  • Gebruik grep -H als je de bestandsnaam van het bestand in de uitvoer wilt opnemen.
  • Gebruik optie 1. En voeg LC_ALL=C vlak voor xargs om veel extra snelheid te krijgen. En je kunt een -P6 vlag op xargs gebruiken om parallel te draaien met (in dit geval) 6 processen (voel je vrij om het aantal van 6 naar iets hoger of lager, om te zien wat ' sneller is op uw computer en tijdens uw zoekopdracht). Referentie: unix.stackexchange.com/questions/131535/…
  • Gebruik van + in plaats van \; zal meerdere bestanden doorgeven aan grep, en als een bestand in die set de tekst ' iets ', al die bestanden zullen de test doorstaan. Dus het zal ' niet doen wat je wilt.

Antwoord

Als u alle overeenkomende regels voor alle bestanden in output.txt wilt opslaan, werkt uw laatste commando, behalve dat u “het vereiste ; aan het einde van het commando.

find . -name "*.py" -type f -exec grep "something" {} \; > output.txt 

Als je wilt dat elke run van grep produceert uitvoer naar een ander bestand, voer een shell uit om de naam van het uitvoerbestand te berekenen en de omleiding uit te voeren.

find . -name "*.py" -type f -exec sh -c "grep "something" <"$0" >"$0.txt"" {} \; 

Opmerkingen

  • de laatste erg leuk: D
  • Om @gilles antwoord uit te breiden om het een beetje informatiever te maken, vooral als de lijst met bestanden je ' mee te maken heeft is groot, je kunt de bestandsnaam (relatief pad) van elk bestand samen met de grep ' ed resultaten rapporteren met behulp van: find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt En als u ' wilt zien e de regelnummers van de grep ' ed regels kunt u natuurlijk grep -n "something"

Answer

Voor de duidelijkheid, grep heeft --include en --exclude argumenten die u kunt gebruiken om de bestanden te filteren die worden doorzocht:

grep -r --include="*.py" "something" > output.txt 

Reacties

  • Ten minste GNU grep doet het.

Antwoord

Gebruik tee:

find . -name "*.py" | tee output.txt | xargs grep "something" 

Het voorbehoud is dat als je bestanden hebt met speciale tekens (inclusief spaties) die xargs en grep niet “goed werken met (a file.txt wordt geïnterpreteerd als twee bestanden, a en file.txt). Het alternatief hiervoor is om ofwel de -x of -print0 te gebruiken, maar beide zullen je output.txt. De -x zal \ gebruiken om aan bepaalde speciale tekens te ontsnappen en dit is in output.txt.De -print0 gebruikt een nulbyte als veldscheidingsteken (waarvoor ook xargs -0 nodig is) en output.txt ziet eruit als een lange aaneengesloten regel tekst.

Hoe je hiermee omgaat (of niet), is aan jou.

Antwoord

grep -n CThread "`find . -name "*.cpp"`" 

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *