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
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 brugegrep -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"`"
+
i stedet for\;
, vil det forbedre udførelsestiden betydeligt (da det vil sammenfatte argumenter før udførelse indtilARG_MAX
).grep -H
, hvis du vil inkludere filnavnet på filen i output.LC_ALL=C
lige førxargs
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/…+
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.