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

  • Använd + istället för \;, kommer det att förbättra exekveringstiden avsevärt (eftersom det kommer att sammanfoga argument före körning tills ARG_MAX).
  • Nu förstår jag kraften i xargs! Tack!
  • Använd grep -H om du vill inkludera filnamnet på filen i utdata.
  • Använd alternativ 1. Och lägg till LC_ALL=C precis före xargs 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/…
  • Använda + 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.

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ända grep -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"`" 

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *