Sto cercando di eseguire il seguente comando:

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

Questo sta restituendo un errore:

find: missing argument to -exec 

Non riesco “a vedere cosa cè di sbagliato in questo comando, poiché sembra corrispondere alla pagina man :

-exec command {} +

Questa variante dellopzione -exec esegue il comando specificato sui file selezionati, ma la riga di comando è costruita aggiungendo alla fine ogni nome di file selezionato; il numero totale di invocazioni del comando sarà molto inferiore al numero di file corrispondenti. La riga di comando è costruita più o meno nello stesso modo in cui xargs costruisce il suo righe di comando. Nel comando è consentita una sola istanza di “{}”. Il comando viene eseguito nella directory iniziale.

Ho anche provato:

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

Commenti

  • Hai provato a sfuggire al + alla fine? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
  • Forse stai utilizzando una vecchia versione di GNU find. Sebbene la variante -exec cmd {} + sia POSIX ed è disponibile dagli anni 80, GNU lha aggiunta solo (relativamente) di recente (2005). Cosa ti dice find --version?
  • @Koveras, sarebbe tutto allora. -exec {} + è stato aggiunto nella 4.2.12 nel 2005. Nelle vecchie scoperte GNU, puoi utilizzare -print0 | xargs -r0 (non POSIX) per ottenere qualcosa simile. 4.1 è del 1994.
  • JRFerguson ha sottolineato (in una risposta che è stata eliminata) che il -name pattern gli argomenti devono essere tra virgolette: -name "*.c" -o -name "*.h". Questo è vero, sebbene non sia correlato allerrore -exec. Noterai che tutte le altre risposte mettono i caratteri jolly tra virgolette, anche se solo Gilles lo menziona. … (Continua)
  • (Continua)… la risposta di jlliagre comprime lespressione del nome in -name "*.[ch]" senza spiegazione. Questo ha i vantaggi di semplificare la riga di comando e, in particolare, di eliminare -o. Trovare espressioni che coinvolgono -o sono difficili da ottenere correttamente. Il tuo è sbagliato; se il tuo comando è corretto in modo che non vada in errore (come nella risposta di Gilles), verrà eseguito grep solo su .h File. Devi fare '(' -name '*.c' -o -name '*.h' ')'.

Risposta

Cera diversi problemi con i tuoi tentativi, inclusi i backtick utilizzati al posto delle virgolette (rimossi nelle modifiche successive alla domanda), virgolette mancanti dove sono richieste, virgolette extra dove sono inutili, parentesi mancanti nel gruppo -o clausole e diverse implementazioni di find utilizzate (vedere i commenti e la chat per i dettagli).

Ad ogni modo, il comando può essere semplificato in questo modo:

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

o, se dovessi usare una versione arcaica GNU find, dovrebbe sempre funzionare:

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

Commenti

  • Spiacenti, dovevano essere virgolette non backtick.
  • Le virgolette sarebbero inutili come {} non ha alcun significato specifico per la shell.
  • Dalle pagine man di find: ” La stringa ‘ { } ‘ è sostituito dal nome del file corrente in fase di elaborazione ovunque si trovi negli argomenti del comando, non solo negli argomenti in cui è solo, come in alcune versioni di find. Potrebbe essere necessario eseguire lescape di entrambe queste costruzioni (con un ‘ \ ‘) o citarle per proteggerle dallespansione della shell. ”
  • Lho effettivamente letto nella pagina di manuale ma il fatto è che non esiste una shell di cui ‘ sono a conoscenza che richiede la citazione delle parentesi graffe. Quale shell stai usando?
  • bash. Con o senza le virgolette ricevo comunque lerrore.

Risposta

“argomento mancante per -exec “di solito significa che largomento di – exec manca del suo terminatore. Il terminatore deve essere un argomento contenente solo il carattere ; (che deve essere citato in un comando della shell, quindi “è tipicamente scritto \; o ";") o due argomenti successivi contenenti {} e +.

Stephane Chazelas ha identificato che “stai utilizzando una versione precedente di GNU che non supporta -exec … {} +, solo -exec {} \;.Sebbene GNU sia stato lultimo ad adottare -exec … {} +, ti consiglio di procurarti una suite di strumenti meno antica (come Cygwin , che include git e molto altro ancora, o GNUwin32 , che manca di git ma “t ha il cattivo-impiegato-che-cerca-di-usare-linux -but-we-impose-windows vibe che Cygwin dà). Questa funzione è stata aggiunta nella versione 4.2.12, oltre 9 anni fa (era lultima funzionalità identificata per rendere GNU find Conforme a POSIX).

Se vuoi restare fedele a una vecchia ricerca GNU, puoi usare -print0 con xargs -0 per ottenere una funzionalità simile: esecuzione di comandi raggruppati, supporto di nomi di file arbitrari.

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

Cita sempre i caratteri jolly su find riga di comando. Altrimenti, se ti capita di eseguire questo comando da una directory contenente file .c, il *.c non quotato woul d essere espanso nellelenco di .c file nella directory corrente.

Aggiunta di /dev/null a grep la riga di comando è un trucco per garantire che grep stamperà sempre il nome del file, anche se find trova una singola corrispondenza. Con GNU find, un altro metodo è passare lopzione -H.

Commenti

  • Cosa fai intendi per cattivo dipendente che cerca di usare Linux ma noi imponiamo latmosfera di Windows che Cygwin dà?
  • GNUwin32 non ‘ non mi aspettavo 🙁
  • Vedi i miei commenti sulla domanda.
  • Le virgolette attorno al semi sono state elaborate allinterno di uno script package.json.

Risposta

Se un comando come

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

restituisce un errore

find: missing argument to -exec 

la causa probabile è troppo vecchia GNU find che non supporta la sintassi -exec mycommand {} +. In tal caso, la sostituzione a basso rendimento consiste nelleseguire -exec mycommand {} \; che eseguirà mycommand una volta per ogni target trovato invece di raccogliere più target ed eseguendo mycommand solo una volta.

Tuttavia, GNU find doe s non supporta ad es.

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

perché GNU find supporta solo la combinazione letterale {} + invece di {} additional parameters + più generico. Tieni presente che non può esserci nulla tra le parentesi graffe e il carattere +. Se lo provi, otterrai lo stesso errore:

find: missing argument to -exec 

La soluzione alternativa è utilizzare la sintassi {} additional parameters \; che funziona ma eseguirà il comando una volta per ogni destinazione trovata. Se hai bisogno di più prestazioni con GNU find devi scrivere uno script wrapper che possa aggiungere parametri aggiuntivi agli argomenti forniti. Qualcosa come

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

dovrebbe essere abbastanza buono. Oppure, se non vuoi creare un file temporaneo, puoi usare una riga per cambiare lordine dei parametri in questo modo:

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

che eseguirà mycommand {list of ttf files} extra arguments. Tieni presente che potresti dover raddoppiare i caratteri speciali di escape per la bash dopo il flag -c.

Commenti

  • (1) La parte di cui sopra che risponde effettivamente alla domanda era già stata data da altre persone. (2) Ciò che stai descrivendo non è un difetto o una carenza in GNU find, ma il comportamento corretto specificato da POSIX .
  • +1 Infine, qualcuno che risponde al motivo per cui parametri aggiuntivi non ‘ non funzionano! Sembra una carenza nella definizione POSIX.
  • Se ‘ utilizzi GNU find tu ‘ probabilmente hai GNU cp. In questo caso puoi find ... -exec cp --target-directory ~/.fonts {} + per mantenere {} alla fine della stringa di esecuzione.

Risposta

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

ha ricevuto errore find: missing argument to ``-exec".

Laggiunta di spazio tra {} e \ ha risolto il problema:

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

Commenti

  • Non è presente alcun problema di questo tipo nel find comando nella domanda in questione.
  • In Domanda non è, va bene, che ho capito, ma il problema è lo stesso ” trova: argomento mancante a “ -exec ‘ “, Il problema può essere dovuto a 2 motivi diversi, ho risposto perché ho visto la stessa dichiarazione del problema.
  • @Kusalananda good grief, il noob ha fornito una soluzione per lerrore segnalato che è dichiarato dallOP sia nel titolo che nel corpo della domanda.
  • @bvj La domanda tratta esplicitamente con la forma + dellopzione -exec per find. Questa risposta corregge un problema che lutente che pone la domanda non ha.

Risposta

Ho avuto il mio quota di mal di testa con la sintassi exec in passato. quasi tutti i giorni ora preferisco la sintassi bash più carina:

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

Presenta alcune limitazioni quando si desidera trattare i file come un gruppo, poiché ciascuno viene valutato in modo seriale, ma puoi reindirizzare loutput altrove benissimo

Commenti

  • Anche se tende a funzionare, è significativamente meno utile della versione pure-find perché non può gestire correttamente i file con spazi bianchi nel nome.
  • No, non ‘ farlo. Questo si interrompe non appena i file contengono spazi e altri caratteri “strani”. Questo è anche più complesso e più lento di find … -exec … \;, quindi ‘ non cè motivo di usarlo anche se sai che i nomi dei tuoi file sono tame.
  • questo è stato utile per la mia situazione in cui avevo bisogno di eseguire più righe di logica in base ai nomi dei file (come rimuovere i caratteri, creare directory e quindi spostare i file). Cercare di trovare per fare più cose in una exec è stato un gran mal di testa per i 5 minuti che volevo dedicare a questo. I miei nomi di file erano docili e questo ha risolto il mio problema 🙂

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *