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
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 natuurlijkgrep -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"`"
+
in plaats van\;
, zal het de uitvoeringstijd aanzienlijk verbeteren (aangezien het argumenten voorafgaand aan de uitvoering zal doorgeven totARG_MAX
).grep -H
als je de bestandsnaam van het bestand in de uitvoer wilt opnemen.LC_ALL=C
vlak voorxargs
om veel extra snelheid te krijgen. En je kunt een-P6
vlag opxargs
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/…+
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.