Yritän suorittaa seuraavan komennon:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar "{}" + 

Tämä palauttaa virheen:

find: missing argument to -exec 

En voi nähdä, mitä tässä komennossa on vikaa, koska se näyttää vastaavan man-sivua :

-exec-komento {} +

Tämä -exec-vaihtoehdon muunnos suorittaa määritetyn komennon valituissa tiedostoissa, mutta komentorivi rakennetaan liittämällä jokainen valittu tiedostonimi loppuun; komennon kokonaismäärä on paljon pienempi kuin vastaavien tiedostojen määrä. Komentorivi on rakennettu samalla tavalla kuin xargs rakentaa sen komentorivit. Vain yksi ”{}” -esiintymä on sallittu komennossa. Komento suoritetaan aloitushakemistossa.

Yritin myös:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar {} + find a/folder b/folder -name *.c -o -name *.h -exec "grep -I foobar" {} + find a/folder b/folder -name *.c -o -name *.h -exec "grep -I foobar" "{}" + find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar "{}" + find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar "{}" + find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar "{}" \+ 

Kommentit

  • Oletko yrittänyt paeta sivulta + lopussa? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
  • Saatat käyttää GNU: n vanhaa versiota find. Vaikka -exec cmd {} + -vaihtoehto on POSIX ja sitä on ollut saatavilla 80-luvulta lähtien, GNU find lisäsi sen vasta (suhteellisen) äskettäin (2005). Mitä find --version kertoo sinulle?
  • @Koveras, se olisi silloin. -exec {} + lisättiin 4.2.12 vuonna 2005. Vanhemmissa GNU-löydöissä voit käyttää (ei-POSIX) -print0 | xargs -r0 -palvelua saadaksesi jotain samanlainen. 4.1 on vuodelta 1994.
  • JRFerguson huomautti (poistetussa vastauksessa), että malli -name argumentit tulee lainata: -name "*.c" -o -name "*.h". Tämä on totta, vaikka se ei liity -exec -virheeseen. Huomaat, että kaikki muut vastaukset laittavat yleismerkit lainausmerkkeihin, vaikka vain Gilles mainitsee sen. … (Jatkuu)
  • (jatkuu) … jlliagren vastaus kutistaa nimilausekkeen -name "*.[ch]" ilman selityksiä. Tämän etuna on yksinkertaistaa komentoriviä ja erityisesti poistaa -o. Löydä lausekkeita, joihin liittyy -o, on vaikea saada oikein. Sinun on väärässä; Jos komentosi on korjattu siten, että se ei vikaa (kuten Gillesin vastauksessa), se suoritetaan grep vain .h tiedostot. Sinun on tehtävä '(' -name '*.c' -o -name '*.h' ')'.

vastaus

useita yrityksiäsi koskevia kysymyksiä, mukaan lukien lainausmerkkien sijaan käytetyt takamerkit (poistettu kysymyksen myöhemmissä muokkauksissa), puuttuvat lainausmerkit, jos niitä tarvitaan, ylimääräiset lainausmerkit, jos ne ovat hyödyttömiä, puuttuvat sulkeet ryhmään -o lausekkeet ja käytetyt find -toteutukset (katso lisätietoja kommenteista ja chatista).

Joka tapauksessa komentoa voidaan yksinkertaistaa seuraavasti:

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} + 

tai, jos käytät arkaaista GNU-hakuversiota, tämän pitäisi toimia aina:

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} \; 

Kommentit

  • Hups, niiden oli tarkoitus olla lainausmerkkejä, ei backtickeja.
  • Lainaukset olisivat hyödyttömiä, koska {}: lla ei ole tarkkaa merkitystä kuorelle.
  • Löydetyt man-sivut: ” Merkkijono ’ { } ’ on korvataan nykyisellä tiedostonimellä, jota käsitellään kaikkialla, se esiintyy komennon argumenteissa, ei pelkästään argumenteissa, joissa se on yksin, kuten joissakin version versioissa. Molemmat rakenteet saatetaan joutua välttämään (’ \ ’) tai lainattava niiden suojaamiseksi kuoren laajentumiselta. ”
  • Luin todellakin sen manuaalisivulta, mutta tosiasia ei ole kuorta

m tietoinen se edellyttää lainata kiharaisia aaltosulkeita. Mitä kuorta käytät?

  • bash. Lainausmerkinnöillä tai ilman, saan virheen joka tapauksessa.
  • Vastaa

    ”puuttuu argumentti arvoon -exec ”tarkoittaa yleensä, että argumentista – exec puuttuu terminaattori. Päätteen on oltava joko argumentti, joka sisältää vain merkin ; (joka on lainattava kuorikomennossa, joten se kirjoitetaan yleensä \; tai ";") tai kaksi peräkkäistä argumenttia, jotka sisältävät {} ja +.

    Stephane Chazelas on havainnut , että käytät GNU-haun vanhempaa versiota, joka ei tue -exec … {} +, vain -exec {} \;.Vaikka GNU otti myöhään käyttöön -exec … {} +, suosittelen, että hankit vähemmän antiikkityökalupaketin (kuten Cygwin , joka sisältää gitin ja paljon muuta, tai GNUwin32 , josta puuttuu git, mutta jolla ei ole huono työntekijä-yrittää käyttää-linuxia -but-we-impose-windows vibe, jonka Cygwin antaa). Tämä ominaisuus lisättiin versioon 4.2.12, yli 9 vuotta sitten (se oli viimeinen tunnistettu ominaisuus, joka teki GNU: n find POSIX-yhteensopiva).

    Jos haluat pysyä vanhemmassa GNU-löydöksessä, voit käyttää -print0 kanssa xargs -0 saadaksesi samanlaisen toiminnallisuuden: ryhmitelty komennon suoritus, mikä tukee mielivaltaisia tiedostojen nimiä.

    find a/folder b/folder -name "*.c" -o -name "*.h" -print0 | xargs -0 grep -I foobar /dev/null 

    Lainaa aina jokerit find -komentorivi. Jos muuten suoritat tämän komennon hakemistosta, joka sisältää .c -tiedostoja, lainaamaton *.c woul d laajennetaan nykyisen hakemiston .c -tiedostojen luetteloon.

    /dev/null lisätään grep -komentorivi on temppu, jolla varmistetaan, että grep tulostaa aina tiedostonimen, vaikka find sattuisi löytämään yhden vastaavuuden. GNU-haun avulla toinen tapa on välittää vaihtoehto -H.

    Kommentit

    • Mitä teet Tarkoitatko huono-työntekijä-yrittää käyttää-linux-mutta-asetamme Windows-tunnelmaa, jonka cygwin antaa?
    • GNUwin32 ei ’ ole odottanut 🙁
    • Katso kommenttini / kommenttini kysymykseen.
    • Lainaukset puolityönä toimineet paketista.json-komentosarjassa.

    vastaus

    Jos komento kuten

    find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar {} + 

    palauttaa virheen

    find: missing argument to -exec 

    todennäköinen syy on liian vanha GNU find, joka ei tue syntaksia -exec mycommand {} +. Tällöin heikon suorituskyvyn korvaava on suorittaa -exec mycommand {} \;, joka suorittaa mycommand kerran jokaiselle löydetylle kohteelle sen sijaan, että keräisi useita kohteita ja ajaa mycommand vain kerran.

    GNU find naaras eivät tue esim.

    find . -type f -and -name "*.ttf" -exec cp {} ~/.fonts + 

    koska GNU find tukee vain kirjaimellista yhdistelmää {} + yleisempien {} additional parameters + sijaan. Huomaa, että aaltosulkeiden ja + -merkin välillä ei voi olla mitään. Jos yrität tätä, saat saman virheen:

    find: missing argument to -exec 

    Kiertotapa on käyttää syntaksia {} additional parameters \; joka toimii, mutta suorittaa komennon kerran jokaiselle löydetylle kohteelle. Jos tarvitset lisää suorituskykyä GNU: n kanssa find, sinun on kirjoitettava kääreohjelma, joka voi lisätä parametreja annettuihin argumentteihin. Jotain

     #!/bin/bash exec mycommand "$@" additional parameters  

    pitäisi olla tarpeeksi hyvä. Tai jos et halua luoda väliaikaista tiedostoa, voit muuttaa yhden parametririvin avulla seuraavien parametrien järjestystä:

    find . -type f -and -name "*.ttf" -exec bash -c "mycommand "$@" extra arguments" {} + 

    joka suorittaa mycommand {list of ttf files} extra arguments. Huomaa, että joudut ehkä kaksinkertaistamaan erikoismerkit bashille -c -lipun jälkeen.

    Kommentit

    • (1) Muut ihmiset ovat jo antaneet yllä olevan osan, joka todella vastaa kysymykseen. (2) Kuvaamasi ei ole virhe tai puute GNU: ssa find, mutta POSIXin määrittelemä oikea käyttäytyminen >.
    • +1 Lopuksi joku, joka vastaa miksi muut parametrit eivät toimi ’! Se näyttää olevan puute POSIX-määritelmässä.
    • Jos ’ ve GNU find sinä ’ olet todennäköisesti saanut GNU cp. Tässä tapauksessa voit find ... -exec cp --target-directory ~/.fonts {} + pitää {} suoritusmerkkijonon lopussa.

    vastaus

    find . -type f -perm 0777 -exec chmod 644 {}\;

    sai virheen find: missing argument to ``-exec".

    Välilyönnin lisääminen {} ja \ välillä korjattiin:

    find . -type f -perm 0777 -print -exec chmod 644 {} \;

    Kommentit

    • Tällaista ongelmaa ei ole kohdassa find -komento käsillä olevassa kysymyksessä.
    • Kysymyksessä ymmärsin, että kysymys ei ole hieno, mutta ongelma on sama. ” find: missing argument kohtaan ” -exec ’ ”, ongelma voi ilmetä eri syistä, vastasin, koska näin saman ongelmalausekkeen.
    • @Kusalananda hyvä suru, noob tarjosi ratkaisun ilmoitettuun virheeseen, jonka OP toteaa sekä kysymyksen otsikossa että rungossa.
    • @bvj Kysymys käsittelee nimenomaisesti + -muodon avulla -exec -asetukseksi find. Tämä vastaus korjaa ongelman, jota kysymyksen esittäjällä ei ole.

    Vastaa

    Minulla oli osuus päänsärkyä exec-syntaksilla aiemmin. Useimpina päivinä pidän mieluummin mukavammasta bash-syntaksista:

    for f in `find a/folder b/folder -name "*.[ch]"`; do grep -I foobar $f; done 

    Siinä on joitain rajoituksia, kun haluat käsitellä tiedostoja ryhmänä, koska kutakin arvioidaan sarjaan mutta voit liittää lähdön muualle hienosti.

    Kommentit

    • Vaikka tämä pyrkii toimimaan, se on huomattavasti vähemmän hyödyllinen kuin puhtaan haun versio, koska se ei pysty käsittelemään tiedostoja, joissa on välilyönti nimessä.
    • Ei, älä tee tätä ’. Tämä rikkoo heti, kun tiedostoissa on välilyöntejä ja muita ”outoja” merkkejä. Tämä on myös monimutkaisempi ja hitaampi kuin find … -exec … \;, joten ’ ei ole syytä käyttää tätä, vaikka tiedätkin, että tiedostosi ovat kesyttää.
    • tästä oli hyötyä tilanteessani, jossa minun tarvitsi ajaa useita logiikkarivejä tiedostonimien perusteella (kuten merkkien poistaminen, hakemistojen tekeminen ja sitten tiedostojen siirtäminen). Yritin löytää useita asioita yhdessä exec oli liikaa päänsärkyä viiden minuutin ajan, jonka halusin käyttää tähän. Tiedostonimeni olivat kesyjä ja tämä ratkaisi ongelmani 🙂

    Vastaa

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