A következő parancsot próbálom futtatni:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar "{}" +
Ez hibát eredményez:
find: missing argument to -exec
Nem látom, hogy mi a baj ezzel a paranccsal, mivel úgy tűnik, hogy egyezik a man oldallal :
-exec parancs {} +
Az -exec opciónak ez a változata a megadott parancsot futtatja a kijelölt fájlokon, de a parancssor úgy épül fel, hogy minden egyes kiválasztott fájlnevet hozzáfűz a végéhez; a parancs meghívásainak teljes száma jóval kevesebb lesz, mint az egyeztetett fájlok száma. A parancssor nagyjából ugyanúgy épül fel, mint az xargs parancssorok. A parancsban csak egy “{}” példány engedélyezett. A parancs a kezdő könyvtárban kerül végrehajtásra.
Próbáltam:
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 "{}" \+
Megjegyzések
Válasz
számos probléma a próbálkozásokkal, beleértve az idézőjelek helyett használt háttérjeleket (eltávolítva a kérdés későbbi szerkesztéseiben), hiányzó idézőjelek, ahol szükségesek, extra idézőjelek, ahol haszontalanok, hiányzó zárójelek a -o
záradékok és a find
különböző megvalósításai (lásd a megjegyzéseket és a csevegést a részletekért).
A parancs így is egyszerűsíthető:
find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} +
vagy, ha archaikus GNU keresési verziót használ, ennek mindig működnie kell:
find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} \;
Megjegyzések
- Hoppá, idézőjeleknek, nem pedig backtickeknek szánták őket.
- Az idézetek haszontalanok lennének, mivel
{}
-nek nincs külön jelentése a héj számára. - A man oldalak kereséséből: ” A string ‘ { } ‘ is helyébe az aktuális fájlnév kerül, amelyet mindenhol feldolgoznak, a parancs argumentumaiban fordul elő, nemcsak azokban az argumentumokban, ahol egyedül van, mint a find egyes verzióiban. Előfordulhat, hogy mindkét konstrukciót el kell kerülni (‘ \ ‘), vagy meg kell idézni, hogy megvédje őket a héj általi terjeszkedéstől. div id = “340c16de68”>
Válasz
“hiányzó argumentum a -exec
”általában azt jelenti, hogy a – exec
argumentumnak hiányzik a terminátora. A terminátornak vagy argumentumnak kell lennie, amely csak az ;
karaktert tartalmazza (amelyet egy shell parancsban kell idézni, így általában \;
vagy ";"
), vagy két egymást követő argumentum, amely {}
és +
.
Stephane Chazelas megállapította, hogy a GNU régebbi verzióját használja, amely nem támogatja a -exec … {} +
, csak -exec {} \;
.Bár a GNU a -exec … {} +
késői alkalmazója volt, azt javaslom, hogy szerezzen be egy kevésbé antik eszközcsomagot (például Cygwin , amely magában foglalja a git-et és még sok minden mást, vagy a GNUwin32 , amelyből hiányzik a git, de nincs meg a rosszul alkalmazott-próbálkozó-linux -but-we-impose-windows hangulatot, amelyet a Cygwin ad). Ez a funkció több mint 9 évvel ezelőtt került a 4.2.12-es verzióba (ez volt az utolsó azonosított szolgáltatás, amely a GNU find
POSIX-kompatibilis).
Ha ragaszkodni szeretne egy régebbi GNU-kereséshez, használhatja a -print0
elemet a xargs -0
hasonló funkció eléréséhez: csoportosított parancsfuttatás, tetszőleges fájlnevek támogatása.
find a/folder b/folder -name "*.c" -o -name "*.h" -print0 | xargs -0 grep -I foobar /dev/null
Mindig idézze a helyettesítő karaktereket a find
parancssor. Ellenkező esetben, ha ezt a parancsot egy .c
fájlokat tartalmazó könyvtárból futtatja, a nem idézett *.c
woul d ki kell terjeszteni az aktuális könyvtár .c
fájljainak listájára.
A /dev/null
hozzáadása a
parancssori trükk annak biztosítására, hogy a grep mindig kinyomtassa a fájl nevét, még akkor is, ha find
véletlenül egyetlen egyezést talál. A GNU kereséssel egy másik módszer a -H
opció átadása.
Megjegyzések
- Mit csinálsz azt jelenti, hogy rossz alkalmazottal próbálkoznak a linux használatával, de Windows-hangulatot vetünk be, amelyet a cygwin ad?
- A GNUwin32 nem ‘ nem számít rá 🙁
- Lásd a kérdéshez fűzött megjegyzéseimet.
- A félig körüli idézetek egy pack.json szkripten belül működtek.
Válasz
Ha egy olyan parancs, mint
find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar {} +
hibát ad vissza
find: missing argument to -exec
a valószínű ok túl régi GNU find
, amely nem támogatja a szintaxist -exec mycommand {} +
. Ebben az esetben az alacsony teljesítményű helyettesítés az -exec mycommand {} \;
futtatása, amely minden megtalált célhoz egyszer futtatja a mycommand
-t, több cél összegyűjtése helyett. és a mycommand
futtatását egyszer.
Azonban a GNU find
őz s nem támogatják pl.
find . -type f -and -name "*.ttf" -exec cp {} ~/.fonts +
mert a GNU find
csak a szó szerinti kombinációt támogatja {} +
általánosabb {} additional parameters +
helyett. Vegye figyelembe, hogy a zárójelek és a +
karakter között nem lehet semmi. Ha megpróbálja ezt, ugyanazt a hibát kapja:
find: missing argument to -exec
A megoldás a {} additional parameters \;
szintaxis használata működik, de minden megtalált célhoz egyszer végrehajtja a parancsot. Ha nagyobb teljesítményre van szüksége a GNU find
használatával, meg kell írnia egy burkoló szkriptet, amely további paramétereket csatolhat a megadott argumentumokhoz. Valaminek
#!/bin/bash exec mycommand "$@" additional parameters
elég jónak kell lennie. Vagy ha nem akar ideiglenes fájlt létrehozni, az egyvonalas segítségével megváltoztathatja az ilyen paraméterek sorrendjét:
find . -type f -and -name "*.ttf" -exec bash -c "mycommand "$@" extra arguments" {} +
amely a mycommand {list of ttf files} extra arguments
. Ne feledje, hogy meg kell dupláznia a bash speciális karaktereit a -c
zászló után.
Megjegyzések
! Hiányosságnak tűnik a POSIX-definícióban.
find
te ‘ valószínűleg megkapta a GNU cp
. Ebben az esetben find ... -exec cp --target-directory ~/.fonts {} +
megtarthatja a {}
-t a végrehajtási karakterlánc végén. Válasz
find . -type f -perm 0777 -exec chmod 644 {}\;
hibát kapott find: missing argument to ``-exec"
.
Szóköz hozzáadása {}
és \
között kijavította:
find . -type f -perm 0777 -print -exec chmod 644 {} \;
Megjegyzések
- A
find
parancs a kérdéses kérdésben. - A kérdésben nem jól értettem, de a probléma ugyanaz ” find: missing argument a -exec ‘ ” címre, Probléma más-2 okból adódhat, válaszoltam, mert ugyanazt a problémamegállapítást láttam.
- @Kusalananda jó bánat, a noob megoldást nyújtott a bejelentett hibára, amelyet az OP a kérdés címében és törzsében egyaránt megfogalmaz.
- @bvj A kérdés kifejezetten foglalkozik a
+
formában a-exec
opcióvalfind
. Ez a válasz kijavítja azt a problémát, amely a kérdést feltevő felhasználónak nincs.
Válasz
a fejfájás aránya a múltban az exec szintaxissal. A legtöbb nap inkább a szebb bash szintaxist részesítem előnyben:
for f in `find a/folder b/folder -name "*.[ch]"`; do grep -I foobar $f; done
Van néhány korlátja, amikor a fájlokat csoportként akarja kezelni, mivel mindegyiket sorosan értékelik, de a kimenetet máshol is jól csaphatod
Megjegyzések
- Bár ez hajlamos működni, lényegesen kevésbé hasznos, mint a pure-find verzió, mert nem tudja helyesen kezelni a névben szóközzel rendelkező fájlokat.
- Nem, ezt ne tegye. ‘ Ez megszakad, amint a fájlok szóközöket és más „furcsa” karaktereket tartalmaznak. Ez szintén összetettebb és lassabb, mint a
find … -exec … \;
, tehát ‘ nincs ok arra, hogy ezt akkor is használd, ha tudod, hogy a fájlneveid szelíd. - ez hasznos volt a helyzetemben, amikor több logikai sort kellett futtatnom a fájlnevek alapján (például betűket törölni, könyvtárakat készíteni, majd a fájlokat áthelyezni). Az a próbálkozás, hogy egyszerre több dolgot is meg lehessen csinálni
exec
, túl nagy fejtörést okozott az 5 perc alatt, amelyet erre szántam. A fájlneveim szelídek voltak, és ez megoldotta a problémámat 🙂
+
a végén?find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
find
régi verzióját használja. Noha a-exec cmd {} +
variáns POSIX, és a 80-as évek óta elérhető, a GNU find csak a közelmúltban (2005-ben) tette hozzá. Mit mond neked afind --version
?-exec {} +
2005-ben 4.2.12-ben került hozzáadásra. Régebbi GNU-leleteknél a (nem POSIX)-print0 | xargs -r0
-t használhatja valamire. hasonló.4.1
1994-ből származik.-name
minta az argumentumokat idézni kell:-name "*.c" -o -name "*.h"
. Ez igaz, bár nem kapcsolódik a-exec
hibához. Észre fogja venni, hogy az összes többi válasz idézőjelbe helyezi a helyettesítő karaktereket, bár csak Gilles említi. … (Folytatás)-name "*.[ch]"
-re. Ennek előnyei a parancssor egyszerűsítése és konkrétan a-o
megszüntetése. A-o
kifejezéseket nehéz megtalálni. A tied téved; ha a parancsod javítva van, így nem hibázik (mint Gilles válaszában), akkorgrep
csak a.h
fájlokat. Meg kell tennie'(' -name '*.c' -o -name '*.h' ')'
.