Jeg prøver at køre følgende kommando:

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

Dette returnerer en fejl:

find: missing argument to -exec 

Jeg kan ikke se, hvad der er galt med denne kommando, da det ser ud til at matche mandsiden :

-exec-kommando {} +

Denne variant af optionen -exec kører den angivne kommando på de valgte filer, men kommandolinjen er bygget ved at tilføje hvert valgte filnavn i slutningen; det samlede antal indbydelser til kommandoen vil være meget mindre end antallet af matchede filer. Kommandolinjen er bygget på samme måde som xargs bygger sin kommandolinjer. Kun en forekomst af “{}” er tilladt i kommandoen. Kommandoen udføres i startmappen.

Jeg prøvede også:

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 "{}" \+ 

Kommentarer

  • Har du forsøgt at undslippe + i slutningen? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
  • Du bruger muligvis en gammel version af GNU find. Selvom -exec cmd {} + -varianten er POSIX og har været tilgængelig siden 80erne, fandt GNU kun den (relativt) for nylig (2005). Hvad fortæller find --version?
  • @Koveras, det ville det være dengang. -exec {} + blev tilføjet i 4.2.12 i 2005. I ældre GNU-fund kan du bruge (ikke-POSIX) -print0 | xargs -r0 til at få noget lignende. 4.1 er fra 1994.
  • JRFerguson påpegede (i et svar, der er blevet slettet), at -name mønsteret argumenter skal citeres: -name "*.c" -o -name "*.h". Dette er sandt, selvom det ikke er relateret til -exec -fejlen. Du vil bemærke, at alle de andre svar sætter wildcards i citater, selvom kun Gilles nævner det. … (Fortsat)
  • (fortsat) … jlliagres svar skjuler navnets udtryk til -name "*.[ch]" uden forklaring. Dette har fordelene ved at forenkle kommandolinjen og specifikt fjerne -o. Find udtryk, der involverer -o, er svære at få ret. Din er forkert; hvis din kommando er løst, så den ikke fejler (som i Gilles svar), kører den kun grep.h filer. Du skal gøre '(' -name '*.c' -o -name '*.h' ')'.

Svar

Der var flere problemer med dine forsøg, herunder backticks brugt i stedet for anførselstegn (fjernet i senere redigeringer af spørgsmålet), manglende anførselstegn, hvor de er påkrævet, ekstra anførselstegn, hvor de er ubrugelige, mangler parenteser til gruppe -o klausuler og forskellige implementeringer af find brugt (se kommentarerne og chatten for detaljer).

Under alle omstændigheder kan kommandoen forenkles på denne måde:

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

eller hvis du bruger en arkaisk GNU-findversion, skal dette altid fungere:

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

Kommentarer

  • Ups, de var ment som citater og ikke backticks.
  • Citater ville være ubrugelige som {} har ingen specifik betydning for skallen.
  • Fra find man-sider: ” Strengen ‘ { } ‘ er erstattet af det nuværende filnavn, der behandles overalt, det forekommer i argumenterne til kommandoen, ikke kun i argumenter, hvor det er alene, som i nogle versioner af find. Begge disse konstruktioner skal muligvis undslippes (med en ‘ \ ‘) eller citeres for at beskytte dem mod ekspansion af skallen. ”
  • Jeg læste det faktisk på manualsiden, men faktum er, at der ikke er nogen skal, jeg ‘ er opmærksom på der kræver citering af de krøllede seler. Hvilken skal bruger du?
  • bash. Med eller uden citaterne får jeg alligevel fejlen.

Svar

“mangler argument til -exec ”betyder normalt, at argumentet til – exec mangler sin terminator. Terminatoren skal enten være et argument, der kun indeholder tegnet ; (som skal citeres i en shell-kommando, så det er typisk skrevet \; eller ";") eller to på hinanden følgende argumenter, der indeholder {} og +.

Stephane Chazelas har identificeret at du bruger en ældre version af GNU-find, som ikke understøtter -exec … {} +, kun -exec {} \;.Selvom GNU var en sen adopter af -exec … {} +, anbefaler jeg, at du får en mindre antik værktøjspakke (såsom Cygwin , som inkluderer git og meget mere, eller GNUwin32 , som mangler git, men ikke har den dårlige medarbejder, der prøver at bruge Linux -men-vi-pålæg-windows-stemning, som Cygwin giver). Denne funktion blev tilføjet i version 4.2.12 for over 9 år siden (det var den sidst identificerede funktion til at lave GNU find POSIX-kompatibel).

Hvis du vil holde dig til et ældre GNU-fund, kan du bruge -print0 med xargs -0 for at få en lignende funktionalitet: grupperet kommandokørsel, der understøtter vilkårlige filnavne.

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

Citér altid jokertegnene på find kommandolinje. Hvis du tilfældigvis kører denne kommando fra en mappe, der indeholder .c filer, vil den ikke-citerede *.c woul d udvides til listen over .c filer i det aktuelle bibliotek.

Tilføjelse af /dev/null til grep kommandolinje er et trick for at sikre, at grep altid udskriver filnavnet, selvom find tilfældigvis finder et enkelt match. Med GNU find er en anden metode at videregive indstillingen -H.

Kommentarer

  • Hvad gør du mener med dårlig medarbejder-forsøger at bruge linux-men-vi-pålæg-windows-vibe, som cygwin giver?
  • GNUwin32 har ikke ‘ ikke forventet 🙁
  • Se min kommentar (er) til spørgsmålet.
  • Citaterne omkring semi-arbejdet fra et package.json-script.

Svar

Hvis en kommando som

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

returnerer fejl

find: missing argument to -exec 

den sandsynlige årsag er for gammel GNU find som ikke understøtter syntaks -exec mycommand {} + I så fald er udskiftning med lav ydeevne at køre -exec mycommand {} \; som kører mycommand en gang for hvert fundne mål i stedet for at samle flere mål og kører mycommand kun en gang.

Dog GNU find doe understøtter ikke f.eks.

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

fordi GNU find understøtter kun bogstavelig kombination {} + i stedet for mere generisk {} additional parameters +. Bemærk, at der ikke kan være noget mellem seler og + -tegnet. Hvis du prøver dette, får du den samme fejl:

find: missing argument to -exec 

Løsningen er at bruge syntaks {} additional parameters \; fungerer, men udfører kommandoen en gang for hvert fundet mål. Hvis du har brug for mere ydeevne med GNU find, skal du skrive et wrapper-script, der kan føje yderligere parametre til de givne argumenter. Noget som

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

skal være godt nok. Eller hvis du ikke vil oprette en midlertidig fil, kan du bruge one-liner til at ændre rækkefølgen af parametre som denne:

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

som udføres mycommand {list of ttf files} extra arguments. Bemærk, at du muligvis bliver nødt til at fordoble specialtegn til bash efter -c -flagget.

Kommentarer

  • (1) Den del af ovenstående, der faktisk besvarer spørgsmålet, blev allerede givet af andre mennesker. (2) Det, du beskriver, er ikke en fejl eller mangel i GNU find, men den korrekte adfærd specificeret af POSIX .
  • +1 Endelig svarer en, der svarer, hvorfor yderligere parametre ikke fungerer ‘! Det virker som en mangel på POSIX-definitionen.
  • Hvis du ‘ har GNU find du ‘ har sandsynligvis GNU cp. I dette tilfælde kan du find ... -exec cp --target-directory ~/.fonts {} + for at beholde {} i slutningen af udførelsesstrengen.

Svar

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

fik fejl find: missing argument to ``-exec".

Tilføjelse af mellemrum mellem {} og \ fikset det:

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

Kommentarer

  • Der er ikke noget sådant problem i find kommando i det aktuelle spørgsmål.
  • I spørgsmål er det ikke fint, jeg forstod, men problemet er det samme ” find: manglende argument til “ -exec ‘ “, Problem kan opstå af forskellige-2 årsager, svarede jeg, fordi jeg så den samme problemstilling.
  • @Kusalananda god sorg, noob leverede en løsning på den rapporterede fejl, som er angivet af OP i både titlen og selve spørgsmålet.
  • @bvj Spørgsmålet omhandler eksplicit med + form af -exec mulighed for at find. Dette svar korrigerer et problem, som brugeren, der stiller spørgsmålet, ikke har.

Svar

Jeg havde min andel af hovedpine med exec-syntaksen i fortiden. de fleste dage foretrækker jeg nu den pænere bash-syntaks:

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

Det har nogle begrænsninger, når du vil behandle filerne som en gruppe, da hver vurderes serielt, men du kan pibe output andetsteds fint

Kommentarer

  • Selvom dette har tendens til at fungere, er det betydeligt mindre nyttigt end den ren-find version, fordi den kan ikke håndtere filer med hvidt mellemrum i navnet korrekt.
  • Nej, ikke ‘ gør det ikke. Dette går i stykker, så snart filerne indeholder mellemrum og andre “underlige” tegn. Dette er også mere komplekst og langsommere end find … -exec … \;, så ‘ er ingen grund til at bruge dette, selvom du ved, at dine filnavne er tæmme.
  • dette var nyttigt for min situation, hvor jeg havde brug for at køre flere linjer med logik baseret på filnavne (som at fjerne tegn, lave mapper og derefter flytte filerne). At forsøge at finde at gøre flere ting i en exec var for meget hovedpine i de 5 minutter, jeg ville bruge på dette. Mine filnavne var tamme, og dette løste mit problem 🙂

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *