Jeg prøver å kjøre følgende kommando:

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

Dette returnerer en feil:

find: missing argument to -exec 

Jeg kan ikke se hva som er galt med denne kommandoen, siden det ser ut til å matche mannssiden :

-exec-kommando {} +

Denne varianten av -exec-alternativet kjører den spesifiserte kommandoen på de valgte filene, men kommandolinjen er bygd ved å legge til hvert valgte filnavn på slutten; det totale antallet innkallinger til kommandoen vil være mye mindre enn antall samsvarende filer. Kommandolinjen er bygget på omtrent samme måte som xargs bygger sin kommandolinjer. Bare en forekomst av «{}» er tillatt i kommandoen. Kommandoen utføres i startkatalogen.

Jeg prøvde 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 prøvd å unnslippe + på slutten? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
  • Du bruker kanskje en gammel versjon av GNU find. Selv om -exec cmd {} + -varianten er POSIX og har vært tilgjengelig siden 80-tallet, fant GNU bare den (relativt) nylig (2005). Hva forteller find --version deg?
  • @Koveras, det ville være det da. -exec {} + ble lagt til i 4.2.12 i 2005. I eldre GNU-funn kan du bruke (ikke-POSIX) -print0 | xargs -r0 for å få noe lignende. 4.1 er fra 1994.
  • JRFerguson påpekte (i et svar som er slettet) at -name mønsteret argumenter bør siteres: -name "*.c" -o -name "*.h". Dette stemmer, selv om det ikke er relatert til -exec feilen. Du vil legge merke til at alle de andre svarene gir jokertegnene sitater, selv om bare Gilles nevner det. … (forts.)
  • (forts.) … jlliagres svar kollapser navnuttrykket til -name "*.[ch]" uten forklaring. Dette har fordelene med å forenkle kommandolinjen og spesifikt eliminere -o. Finn uttrykk som involverer -o er vanskelig å få rett. Din er feil; hvis kommandoen din er løst slik at den ikke feiler (som i Gilles svar), vil den kjøre grep bare på .h filer. Du må gjøre '(' -name '*.c' -o -name '*.h' ')'.

Svar

Det var flere problemer med forsøkene dine, inkludert backticks brukt i stedet for anførselstegn (fjernet i senere redigeringer av spørsmålet), manglende anførselstegn der det kreves, ekstra anførselstegn der de er ubrukelige, mangler parenteser til gruppen -o klausuler og forskjellige implementeringer av find brukt (se kommentarene og chatten for detaljer).

Uansett kan kommandoen forenkles slik:

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

eller, hvis du bruker en arkaisk GNU-finnversjon, bør dette alltid fungere:

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

Kommentarer

  • Ups, de var ment å være sitater ikke backticks.
  • Sitater ville være ubrukelige som {} har ingen spesifikk betydning for skallet.
  • Fra finn man-sider: » Strengen ‘ { } ‘ er erstattet av det nåværende filnavnet som behandles overalt det forekommer i argumentene til kommandoen, ikke bare i argumenter der det er alene, som i noen versjoner av find. Begge disse konstruksjonene må kanskje rømmes (med en ‘ \ ‘) eller siteres for å beskytte dem mot utvidelse av skallet. »
  • Jeg leste det faktisk på manualsiden, men faktum er at det ikke er noe skall jeg ‘ er klar over som krever sitering av krøllete bukseseler. Hvilket skall bruker du?
  • bash. Med eller uten anførselstegn får jeg uansett feilen.

Svar

“mangler argument til -exec ”betyr vanligvis at argumentet til – exec mangler terminatoren. Terminatoren må enten være et argument som bare inneholder tegnet ; (som må siteres i en shell-kommando, så det er vanligvis skrevet \; eller ";"), eller to påfølgende argumenter som inneholder {} og +.

Stephane Chazelas har identifisert at du bruker en eldre versjon av GNU-funn som ikke støtter -exec … {} +, bare -exec {} \;.Selv om GNU var en sen adopterer av -exec … {} +, anbefaler jeg at du får en mindre antikk verktøypakke (for eksempel Cygwin , som inkluderer git og mye mer, eller GNUwin32 , som mangler git, men som ikke har den dårlige medarbeideren som prøver å bruke Linux -but-we-impose-windows vibe som Cygwin gir). Denne funksjonen ble lagt til i versjon 4.2.12 for over 9 år siden (det var den siste identifiserte funksjonen for å lage GNU find POSIX-kompatibel).

Hvis du vil holde deg til et eldre GNU-funn, kan du bruke -print0 med xargs -0 for å få en lignende funksjonalitet: gruppert kommandokjøring, som støtter vilkårlige filnavn.

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

Sitat alltid jokertegnene på find kommandolinje. Hvis ikke du kjører denne kommandoen fra en katalog som inneholder .c filer, vil den ikke siterte *.c woul d utvides til listen over .c filer i den aktuelle katalogen.

Legger til /dev/null i grep kommandolinje er et triks for å sikre at grep alltid vil skrive ut filnavnet, selv om find tilfeldigvis finner en enkelt kamp. Med GNU find er en annen metode å overføre alternativet -H.

Kommentarer

  • Hva gjør du mener med dårlig ansatt-prøver-å-bruke-linux-men-vi-pålegger-windows-stemning som cygwin gir?
  • GNUwin32 har ikke ‘ ikke forventet 🙁
  • Se kommentarene mine til spørsmålet.
  • Sitatene rundt semi fungerte fra et package.json-skript.

Svar

Hvis en kommando som

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

returnerer feil

find: missing argument to -exec 

den sannsynlige årsaken er for gammel GNU find som ikke støtter syntaks -exec mycommand {} + I så fall er erstatning med lav ytelse å kjøre -exec mycommand {} \; som vil kjøre mycommand en gang for hvert funnet mål i stedet for å samle flere mål og kjører mycommand bare en gang.

GNU find doe støtter ikke f.eks.

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

fordi GNU find støtter bare bokstavelig kombinasjon {} + i stedet for mer generisk {} additional parameters +. Vær oppmerksom på at det ikke kan være noe mellom klammeparentesene og + -tegnet. Hvis du prøver dette, får du den samme feilen:

find: missing argument to -exec 

Løsningen er å bruke syntaks {} additional parameters \; fungerer, men vil utføre kommandoen en gang for hvert funnet mål. Hvis du trenger mer ytelse med GNU find, må du skrive et wrapper-skript som kan legge til tilleggsparametere til de gitte argumentene. Noe som

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

burde være bra nok. Eller hvis du ikke vil opprette midlertidig fil, kan du bruke en-linje til å endre rekkefølgen på parametere som dette:

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

som vil kjøre mycommand {list of ttf files} extra arguments. Vær oppmerksom på at det kan hende du må dobbeltegne spesialtegn for bash etter -c -flagget.

Kommentarer

  • (1) Den delen av det ovennevnte som faktisk svarer på spørsmålet, var allerede gitt av andre mennesker. (2) Det du beskriver er ikke en feil eller mangel på GNU find, men den riktige oppførselen spesifisert av POSIX .
  • +1 Endelig, noen som svarer på hvorfor flere parametere ikke fungerer ‘! Det virker som en mangel i POSIX-definisjonen.
  • Hvis du ‘ har GNU find du ‘ har sannsynligvis fått GNU cp. I dette tilfellet kan du find ... -exec cp --target-directory ~/.fonts {} + for å beholde {} på slutten av kjøringsstrengen.

Svar

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

fikk feil find: missing argument to ``-exec".

Å legge til mellomrom mellom {} og \ fikset det:

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

Kommentarer

  • Det er ikke noe slikt problem i find kommandoen i det aktuelle spørsmålet.
  • I spørsmål er det ikke greit at jeg forsto det, men problemet er det samme » finn: mangler argument til « -exec ‘ «, Problem kan oppstå av annen-2 grunn, svarte jeg fordi jeg så samme problemstilling.
  • @Kusalananda god sorg, noob ga en løsning for den rapporterte feilen som er angitt av OP i både tittelen og selve spørsmålet.
  • @bvj Spørsmålet handler eksplisitt med + form av -exec alternativet til find. Dette svaret korrigerer et problem som brukeren som stiller spørsmålet ikke har.

Svar

Jeg hadde min andel av hodepine med exec-syntaksen tidligere. de fleste dager nå foretrekker jeg den finere bash-syntaksen:

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

Det har noen begrensninger når du vil behandle filene som en gruppe, ettersom hver blir evaluert serielt, men du kan rense utdataene andre steder helt fint

Kommentarer

  • Selv om dette har en tendens til å fungere, er det betydelig mindre nyttig enn pure-find-versjonen fordi det kan ikke håndtere filer med mellomrom i navnet riktig.
  • Nei, ikke ‘ ikke gjør dette. Dette går i stykker så snart filene inneholder mellomrom og andre «rare» tegn. Dette er også mer komplekst og langsommere enn find … -exec … \;, så ‘ er ingen grunn til å bruke dette selv om du vet at filnavnene dine er tamme.
  • dette var nyttig for min situasjon der jeg trengte å kjøre flere linjer med logikk basert på filnavnene (som å fjerne tegn, lage kataloger og deretter flytte filene). Å prøve å finne å gjøre flere ting i en exec var for mye hodepine i de 5 minuttene jeg ønsket å bruke på dette. Filnavnene mine var tamme, og dette løste problemet mitt 🙂

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *