Bedre at forklare på eksempler.

Jeg kan:

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

Men hvordan kan jeg gemme output i den samme fil til:

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

Jeg kan ikke bare gøre

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

Svar

Hvis jeg forstår dig korrekt, er det hvad du vil gøre:

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

Find alle filer med udvidelse .py, grep kun rækker, der indeholder something og gemme rækkerne i output.txt. Hvis output.txt -filen findes, bliver den afkortet, ellers bliver den oprettes.

Brug af -exec:

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

Jeg indarbejder Chris Downs kommentar her: Ovenstående kommando vil resultere i, at grep udføres så mange gange som find finder vejnavne, der består de givne tests (kun den enkelte test ovenfor). Hvis du dog erstatter \; med en +, kaldes grep med flere stienavne fra find (op til en bestemt grænse).

Se spørgsmål Brug af semikolon (;) vs plus ( +) med exec i find for mere om emnet.

Kommentarer

  • Brug + i stedet for \;, vil det forbedre udførelsestiden betydeligt (da det vil sammenfatte argumenter før udførelse indtil ARG_MAX).
  • Nu forstår jeg kraften i xargs! Tak!
  • Brug grep -H, hvis du vil inkludere filnavnet på filen i output.
  • Brug mulighed 1. Og tilføj LC_ALL=C lige før xargs for at få meget ekstra hastighed. Og du kan bruge et -P6 flag på xargs til at køre parallelt med (i dette tilfælde) 6 processer (du er velkommen til at ændre antallet fra 6 til noget højere eller lavere for at se, hvad ' er hurtigere på din maskine og på din søgning). Reference: unix.stackexchange.com/questions/131535/…
  • Brug af + i stedet for \; sender flere filer til grep, og hvis en fil i det sæt indeholder teksten ' noget ', alle disse filer vil bestå testen. Så det vandt ' ikke, hvad du vil.

Svar

Hvis du vil gemme alle de matchende linjer på tværs af alle filer i output.txt, fungerer din sidste kommando bortset fra at du “mangler det krævede ; i slutningen af kommandoen.

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

Hvis du vil have hver kørsel af grep output til en anden fil, kør en shell for at beregne outputfilnavnet og udfør omdirigering.

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

Kommentarer

  • den sidste rigtig dejlige: D
  • At udvide på @gilles svar for at gøre det lidt mere informativt, især hvis listen over filer du ' re beskæftiger sig med er stort, kan du rapportere filnavnet (relativ sti) for hver fil sammen med grep ' ed resultater ved hjælp af dette: find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt Og hvis du ' gerne vil se e linjenumrene på grep ' ed linjer, du kan selvfølgelig bruge grep -n "something"

Svar

For ordens skyld har grep --include og --exclude argumenter, som du kan bruge til at filtrere de filer, den søger i:

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

Kommentarer

  • Mindst GNU grep gør.

Svar

Brug tee:

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

Advarslen er, hvis du har filer med specialtegn (inklusive mellemrum), som xargs og grep ikke fungerer godt sammen med (a file.txt vil blive fortolket som to filer, a og file.txt). Alternativet til det er at bruge enten -x eller -print0, men en af disse forurener din output.txt. -x bruger \ til at undslippe visse specialtegn, og dette vil være i output.txt.-print0 bruger en nulbyte som en feltseparator (som også kræver xargs -0) og output.txt vil se ud som en lang sammenhængende tekstlinje.

Hvordan du håndterer (eller ikke gør det) er op til dig.

Svar

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

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *