Bedre å forklare på eksempler.
Jeg kan:
find . -name "*.py" -type f > output.txt
Men hvordan kan jeg lagre utdataene i samme fil for:
find . -name "*.py" -type f -exec grep "something" {} \
Jeg kan ikke bare gjøre
find . -name "*.py" -type f -exec grep "something" {} \ > output.txt
Svar
Hvis jeg forstår deg riktig, er det dette du vil gjøre:
find . -name "*.py" -print0 | xargs -0 grep "something" > output.txt
Finn alle filene med utvidelse .py
, grep
bare rader som inneholder something
og lagre radene i output.txt
. Hvis output.txt
-filen eksisterer, blir den avkortet, ellers blir den blir opprettet.
Bruk av -exec
:
find . -name "*.py" -exec grep "something" {} \; > output.txt
Jeg innlemmer Chris Downs kommentar her: Kommandoen ovenfor vil resultere i at grep
blir utført så mange ganger som find
finner stienavn som består de gitte testene (bare singelen test ovenfor). Imidlertid, hvis du bytter ut \;
med en +
, kalles grep
med flere banenavn fra find
(opp til en viss grense).
Se spørsmål Bruk av semikolon (;) vs plus ( +) med exec i finn for mer om emnet.
Kommentarer
Svar
Hvis du vil lagre alle samsvarende linjer på tvers av alle filene i output.txt
, fungerer den siste kommandoen din, bortsett fra at du mangler den nødvendige ;
på slutten av kommandoen.
find . -name "*.py" -type f -exec grep "something" {} \; > output.txt
Hvis du vil at hver kjøring av grep
skal produsere send ut til en annen fil, kjør et skall for å beregne navnet på utdatafilen og utfør omdirigering.
find . -name "*.py" -type f -exec sh -c "grep "something" <"$0" >"$0.txt"" {} \;
Kommentarer
- den siste veldig hyggelig: D
- For å utvide på @gilles svar for å gjøre det litt mer informativt, spesielt hvis listen over filer du ' Når du har å gjøre med er stort, kan du rapportere filnavnet (relativ bane) for hver fil sammen med grep ' ed resultatene ved hjelp av dette:
find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt
Og hvis du ' vil se e linjenumrene til grep ' ed linjene, du kan selvfølgelig brukegrep -n "something"
Svar
For ordens skyld har grep
--include
og --exclude
argumenter som du kan bruke til å filtrere filene den søker i:
grep -r --include="*.py" "something" > output.txt
Kommentarer
- I det minste gjør GNU
grep
.
Svar
Bruk tee
:
find . -name "*.py" | tee output.txt | xargs grep "something"
Advarselen er hvis du har noen filer med spesialtegn (inkludert mellomrom) som xargs
og grep
ikke vil fungere bra med (a file.txt
vil bli tolket som to filer, a
og file.txt
). Alternativet til det er å bruke enten -x
eller -print0
, men en av disse vil forurense output.txt
. -x
vil bruke \
for å unnslippe visse spesialtegn, og dette vil være i output.txt
.-print0
vil bruke en nullbyte som feltutskiller (som også krever xargs -0
) og output.txt
vil se ut som en lang sammenhengende tekstlinje.
Hvordan du takler dette (eller ikke gjør det) er opp til deg.
Svar
grep -n CThread "`find . -name "*.cpp"`"
+
i stedet for\;
, vil det forbedre kjøringstiden betydelig (siden den vil sammenfatte argumenter før kjøring tilARG_MAX
).grep -H
hvis du vil inkludere filnavnet til filen i utdataene.LC_ALL=C
rett førxargs
for å få mye ekstra hastighet. Og du kan bruke et-P6
flagg påxargs
for å kjøre parallelt med (i dette tilfellet) 6 prosesser (endre gjerne tallet fra 6 til noe høyere eller lavere, for å se hva ' er raskere på maskinen din og på søket). Referanse: unix.stackexchange.com/questions/131535/…+
i stedet for\;
vil sende flere filer til grep, og hvis en fil i det settet inneholder teksten ' noe ', alle disse filene vil bestå testen. Så det vant ' ikke det du vil.