Måske er det lidt underligt – og måske er der andre værktøjer til at gøre dette, men, ja ..
Jeg bruger følgende klassiske bash-kommando til at finde alle filer, der indeholder nogle strenge:
find . -type f | xargs grep "something"
Jeg har et stort antal filer på flere dybder første forekomst af “noget” er nok for mig, men find fortsætter med at søge og tager lang tid at færdiggøre resten af filerne. Hvad jeg gerne vil gøre er noget som en “feedback” fra grep tilbage for at finde, så find kunne stoppe med at søge efter flere filer. Er det sådan muligt?
Svar
Hold det bare inden for find:
find . -type f -exec grep "something" {} \; -quit
Sådan fungerer det:
-exec
fungerer, når -type f
vil være sandt. Og fordi grep
returnerer 0
(success / true) når har et match, -quit
udløses.
Svar
find -type f | xargs grep e | head -1
gør nøjagtigt det: når head
afsluttes, meddeles rørets midterste element med et” brudt rør “signal, afsluttes igen og underretter find
. Du skal se en meddelelse som
xargs: grep: terminated by signal 13
som bekræfter dette.
Kommentarer
- +1 til forklaring og alternativet, selvom det andet svar forekommer mig mere elegant, da det er mere selvforsynende
Svar
For at gøre dette uden at skifte værktøj: (Jeg elsker xargs)
#!/bin/bash find . -type f | # xargs -n20 -P20: use 10 parallel processes to grep files in batches of 20 # grep -m1: show just on match per file # grep --line-buffered: multiple matches from independent grep processes # will not be interleaved xargs -P10 -n20 grep -m1 --line-buffered "$1" 2> >( # Error output (stderr) is redirected to this command. # We ignore this particular error, and send any others back to stderr. grep -v "^xargs: .*: terminated by signal 13$" >&2 ) | # Little known fact: all `head` does is send signal 13 after n lines. head -n 1
Kommentarer
- +1 vidste aldrig, at xargs ville have sådanne multitasking-muligheder – tak også for andre kommentarer! 🙂