Oletetaan, että haluan löytää kaikki .txt -tiedostot ja etsiä joitain merkkijonoja. Teen:

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

Entä jos haluan tehdä monimutkaisemman suodatuksen, kuten tämä:

egrep something file.txt | egrep somethingelse | egrep other 

Inside find -exec? (tai vastaava)

Muista, että etsin ratkaisua, jonka voin helposti kirjoittaa, kun tarvitsen sitä. Tiedän, että tämä voidaan tehdä muutamalla rivillä käyttämällä komentotulkkikomentosarjaa, mutta sitä en etsi.

Vastaa

Jos sinun täytyy tehdä se etsinnän sisällä, sinun on soitettava komentotulkki:

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

Muita vaihtoehtoja ovat sen sijaan xargs:

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

Tai , paljon turvallisempi mielivaltaisille tiedostonimille (olettaen, että find tukee -print0):

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

Tai voit käyttää vain kuorisilmukkaa:

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

Kommentit

  • Ensimmäinen on juuri sitä mitä etsin. Erittäin yksinkertainen ja tarpeeksi pieni kirjoitettavaksi tarpeen mukaan. Kiitos.
  • … ja xargs voidaan käyttää myös nimellä xargs -I {} sh -c '...' sh {}, jos haluaa (se tekee on mahdollista suorittaa rinnakkaisia töitä -P -toiminnolla, jos niin halutaan. vastaus ”>

    Muokkaa: Tämä vastaus ei ole suositeltava , mutta jätetään tähän vertailua ja havainnollistamista varten mahdollisesti vaarallisista sudenkuopista bash-komentosarjoissa.


    Voit laittaa bash (tai muun kuoren) komentoosi -exec:

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

    Yksi tämän tekemisen haittapuolista on, että se luo enemmän sisäkkäisten lainausongelmien mahdollisuus, kun komentosi monimutkaistuvat. Jos haluat välttää sen, voit jakaa sen for -loopiksi:

     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  

    kommentit

    • Ensimmäinen on juuri sitä, mitä etsin. Erittäin yksinkertainen ja tarpeeksi pieni kirjoitettavaksi tarpeen mukaan. Kiitos.
    • Tuo for -silmukka on erittäin huono idea. Tunnetaan myös nimellä bash # 1 .
    • Tämä "{}" ensimmäisessä komennossasi voi jopa johtaa koodin injektointiin. Kuvittele, että sinulla on tiedostoja minulta ja siellä ' s on tiedosto, jonka nimi on kirjaimellisesti " & rm -rf ~ & : ".txt. Sinun onneksi -type -f on virheellinen, se vain tallensi kotihakemistosi. Korjaa kirjoitusvirhe ja yritä uudelleen. 🙂 terdon teki sen oikein: find … -exec sh -c '… "$1" …' foo {} \;.
    • Kiitos tiedoista! Joo, -type -f on kirjoitusvirhe, jonka teen jatkuvasti käytettäessä find, enkä ' ei huomaa sitä vastauksessani. Oho. terdon ' vastaus on parempi, mutta jätän tämän ' vastaamaan.
    • @terdon: tx mywiki.wooledge.org -sivun viittaamiseen. ' on mukavaa saada joukko yleislääkäreitä siististi yhteen paikkaan.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *