Lad os antage, at jeg vil finde alle .txt filer og søge efter en streng. Jeg ville gøre:

find ./ -type f -name "*.txt" -exec egrep -iH "something" "{}" \; 

Hvad hvis jeg vil foretage en mere kompleks filtrering, som denne:

egrep something file.txt | egrep somethingelse | egrep other 

Inside find -exec? (eller lignende)

Husk, at jeg leder efter en løsning, som jeg let kunne skrive, når jeg har brug for det. Jeg ved, at dette kunne gøres med et par linjer ved hjælp af et shell-script, men det er ikke det, jeg leder efter.

Svar

Hvis du skal gøre det inden for find, skal du ringe til en shell:

find ./ -type f -name "*.txt" -exec sh -c "grep -EiH something "$1" | grep -E somethingelse | grep -E other" sh {} \; 

Andre alternativer inkluderer at bruge xargs i stedet:

find ./ -type f -name "*.txt" | xargs -I{} grep -EiH something {} | grep -EiH somethingelse | grep -EiH other 

Eller , meget sikrere for vilkårlige filnavne (forudsat at din find understøtter -print0):

find ./ -type f -name "*.txt" -print0 | xargs -0 grep -EiH something {} | grep -Ei somethingelse | grep -Ei other 

Eller du kan bare bruge en shell-loop i stedet:

find ./ -type f -name "*.txt" -print0 | while IFS= read -d "" file; do grep -Ei something "$file" | grep -Ei somethingelse | grep -Ei other done 

Kommentarer

  • Den første er nøjagtigt hvad jeg ledte efter. Ekstremt enkel og lille nok til at skrive afhængigt af mine behov. Tak.
  • … og xargs kunne også bruges som xargs -I {} sh -c '...' sh {}, hvis man ville (det gør det er muligt at køre parallelle job med -P hvis man vil).

Svar

Rediger: Dette svar er foretrækkes ikke , men er her til sammenligning og illustration af potentielt farlige faldgruber i bash scripting.


Du kan sætte bash (eller en anden shell) som din -exec kommando:

 find -type -f -name "*.txt" -exec bash -c "egrep -iH something "{}" | egrep somethingelse | egrep other" \;  

En af ulemperne ved at gøre det på denne måde er, at det skaber mere potentiale for nestede citatproblemer, da dine kommandoer bliver mere komplekse. Hvis du vil undgå det, kan du bryde det ud i en for -loop:

 for i in $(find -type -f -name "*.txt"); do if egrep -iH something "$i" | egrep somethingelse | egrep other; then echo "Found something: $i" fi done  

Kommentarer

  • Den første er nøjagtigt hvad jeg ledte efter. Ekstremt enkel og lille nok til at skrive afhængigt af mine behov. Tak.
  • At for loop er en meget dårlig idé. Også kendt som bash faldgrube # 1 .
  • Denne "{}" i din første kommando kan endda føre til kodeinjektion. Forestil dig, at du har filer fra mig, og der er ' en fil, der bogstaveligt talt hedder " & rm -rf ~ & : ".txt. Heldigvis for dig er -type -f ugyldig, det har bare gemt din hjemmekatalog. Ret skrivefejl og prøv igen. 🙂 terdon gjorde det rigtigt: find … -exec sh -c '… "$1" …' foo {} \;.
  • Tak for informationen! Ja, -type -f er en tastefejl, jeg konstant laver, når jeg bruger find, og jeg gjorde ikke ' t bemærker det i mit svar. Ups. terdon ' s svar er bedre, men jeg ' lader dette være til sammenligningsformål.
  • @terdon: tx for at henvise til mywiki.wooledge.org siden. Det er ' dejligt at have en flok læger samlet på et sted.

Skriv et svar

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