Bättre att förklara på exempel.
Jag kan:
find . -name "*.py" -type f > output.txt
Men hur kan jag lagra utdata i samma fil för:
find . -name "*.py" -type f -exec grep "something" {} \
Jag kan inte bara göra
find . -name "*.py" -type f -exec grep "something" {} \ > output.txt
Svar
Om jag förstår dig rätt är det här du vill göra:
find . -name "*.py" -print0 | xargs -0 grep "something" > output.txt
Hitta alla filer med tillägget .py
, grep
endast rader som innehåller something
och spara raderna i output.txt
. Om output.txt
-filen finns, kommer den att trunkeras, annars kommer att skapas.
Med -exec
:
find . -name "*.py" -exec grep "something" {} \; > output.txt
Jag innehåller Chris Downs kommentera här: Kommandot ovan kommer att resultera i att grep
körs så många gånger som find
hittar sökvägen som klarar de givna testerna (endast den enskilda test ovan). Om du dock ersätter \;
med en +
kallas grep
med flera sökvägar från find
(upp till en viss gräns).
Se fråga Använda semikolon (;) vs plus ( +) med exec i hitta för mer om ämnet.
Kommentarer
Svar
Om du vill spara alla matchande rader över alla filer i output.txt
fungerar ditt sista kommando, förutom att du saknar nödvändigt ;
i slutet av kommandot.
find . -name "*.py" -type f -exec grep "something" {} \; > output.txt
Om du vill att varje körning av grep
mata ut till en annan fil, kör ett skal för att beräkna utdatafilnamnet och utföra omdirigeringen.
find . -name "*.py" -type f -exec sh -c "grep "something" <"$0" >"$0.txt"" {} \;
Kommentarer
- den sista riktigt trevliga: D
- Att utöka på @gilles svar för att göra det lite mer informativt, särskilt om listan över filer du ' om hanteringen är stor kan du rapportera filnamnet (relativ sökväg) för varje fil tillsammans med grep ' ed resultat med detta:
find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt
Och om du ' vill se e radnumren för grep ' ed rader kan du naturligtvis användagrep -n "something"
Svar
För ordens skull har grep
--include
och --exclude
argument som du kan använda för att filtrera filerna det söker efter:
grep -r --include="*.py" "something" > output.txt
Kommentarer
- Åtminstone gör GNU
grep
.
Svar
Använd tee
:
find . -name "*.py" | tee output.txt | xargs grep "something"
Förbehållet är om du har några filer med specialtecken (inklusive mellanslag) som xargs
och grep
inte fungerar bra med (a file.txt
tolkas som två filer, a
och file.txt
). Alternativet till det är att använda antingen -x
eller -print0
, men någon av dessa kommer att förorena din output.txt
. -x
använder \
för att undkomma vissa specialtecken och detta kommer att finnas i output.txt
.-print0
använder en nollbyte som fältseparator (som också kräver xargs -0
) och output.txt
kommer att se ut som en lång sammanhängande textrad.
Hur du hanterar (eller inte gör det) är upp till dig.
Svar
grep -n CThread "`find . -name "*.cpp"`"
+
istället för\;
, kommer det att förbättra exekveringstiden avsevärt (eftersom det kommer att sammanfoga argument före körning tillsARG_MAX
).grep -H
om du vill inkludera filnamnet på filen i utdata.LC_ALL=C
precis förexargs
för att få mycket extra hastighet. Och du kan använda en-P6
-flagga påxargs
för att köra parallellt med (i det här fallet) 6 processer (ändra gärna antalet från 6 till något högre eller lägre, för att se vad ' är snabbare på din maskin och på din sökning). Referens: unix.stackexchange.com/questions/131535/…+
istället för\;
skickar flera filer till grep, och om någon fil i den uppsättningen innehåller texten ' något ', alla dessa filer klarar testet. Så det vann ' inte vad du vill.