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

  • Bruk + i stedet for \;, vil det forbedre kjøringstiden betydelig (siden den vil sammenfatte argumenter før kjøring til ARG_MAX).
  • Nå forstår jeg kraften til xargs! Takk!
  • Bruk grep -H hvis du vil inkludere filnavnet til filen i utdataene.
  • Bruk alternativ 1. Og legg til LC_ALL=C rett før xargs 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/…
  • Bruke + 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.

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 bruke grep -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"`" 

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *