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
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?
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 GNUcp
. Tässä tapauksessa voitfind ... -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
-asetukseksifind
. 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 🙂
+
lopussa?find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
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?-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.-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)-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 suoritetaangrep
vain.h
tiedostot. Sinun on tehtävä'(' -name '*.c' -o -name '*.h' ')'
.