Jessaye dexécuter la commande suivante:

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

Ceci renvoie une erreur:

find: missing argument to -exec 

Je ne peux « pas voir ce qui ne va pas avec cette commande, car elle semble correspondre à la page de manuel :

-exec command {} +

Cette variante de loption -exec exécute la commande spécifiée sur les fichiers sélectionnés, mais la ligne de commande est construite en ajoutant chaque nom de fichier sélectionné à la fin; le nombre total dappels de la commande sera bien inférieur au nombre de fichiers correspondants. La ligne de commande est construite à peu près de la même manière que xargs construit son lignes de commande. Une seule instance de « {} » est autorisée dans la commande. La commande est exécutée dans le répertoire de départ.

Jai aussi essayé:

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

Commentaires

  • Avez-vous essayé déchapper à + à la fin? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
  • Vous utilisez peut-être une ancienne version de GNU find. Bien que la variante -exec cmd {} + soit POSIX et soit disponible depuis les années 80, GNU find la seulement ajoutée (relativement) récemment (2005). Que vous dit find --version?
  • @Koveras, ce serait alors tout. -exec {} + a été ajouté dans la version 4.2.12 en 2005. Dans les anciennes découvertes GNU, vous pouvez utiliser le -print0 | xargs -r0 (non-POSIX) pour obtenir quelque chose similaire. 4.1 date de 1994.
  • JRFerguson a fait remarquer (dans une réponse qui a été supprimée) que le modèle -name les arguments doivent être entre guillemets: -name "*.c" -o -name "*.h". Cest vrai, même si cela na aucun rapport avec lerreur -exec. Vous remarquerez que toutes les autres réponses mettent les jokers entre guillemets, bien que seul Gilles le mentionne. … (Suite)
  • (suite)… La réponse de jlliagre réduit lexpression de nom à -name "*.[ch]" sans explication. Cela présente les avantages de simplifier la ligne de commande et, en particulier, déliminer les -o. Il est difficile de trouver des expressions impliquant -o. Le vôtre est faux; si votre commande est corrigée de manière à ne pas afficher derreur (comme dans la réponse de Gilles), elle exécutera grep uniquement sur le .h des dossiers. Vous devez faire '(' -name '*.c' -o -name '*.h' ')'.

Réponse

Il y a eu plusieurs problèmes avec vos tentatives, y compris des rétroprojecteurs utilisés à la place des guillemets (supprimés lors des modifications ultérieures de la question), des guillemets manquants là où ils sont nécessaires, des guillemets supplémentaires là où ils sont inutiles, des parenthèses manquantes pour le groupe -o, et différentes implémentations de find utilisées (voir les commentaires et le chat pour plus de détails).

Quoi quil en soit, la commande peut être simplifiée comme ceci:

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

ou, si vous utilisez une version de recherche GNU archaïque, cela devrait toujours fonctionner:

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

Commentaires

  • Oups, ils étaient censés être des guillemets et non des backticks.
  • Les citations seraient inutiles car {} na pas de signification spécifique pour le shell.
  • À partir des pages de manuel de recherche:  » La chaîne ‘ { } ‘ est remplacé par le nom de fichier en cours de traitement partout où il apparaît dans les arguments de la commande, pas seulement dans les arguments où il est seul, comme dans certaines versions de find. Ces deux constructions peuvent avoir besoin dêtre échappées (avec un ‘ \ ‘) ou entre guillemets pour les protéger de lexpansion par le shell.  »
  • Jai bien lu cela dans la page de manuel mais le fait est quil ny a pas de shell que je ‘ connais cela nécessite de citer les accolades. Quel shell utilisez-vous?
  • bash. Avec ou sans les guillemets, jobtiens lerreur de toute façon.

Réponse

« argument manquant à -exec « signifie généralement que largument de – exec na pas de terminateur. Le terminateur doit être soit un argument contenant uniquement le caractère ; (qui doit être entre guillemets dans une commande shell, il est donc généralement écrit \; ou ";"), ou deux arguments successifs contenant {} et +.

Stéphane Chazelas a identifié que vous « utilisez une ancienne version de GNU find qui ne prend pas en charge -exec … {} +, uniquement -exec {} \;.Bien que GNU ait été lun des derniers à adopter -exec … {} +, je vous recommande de vous procurer une suite doutils moins ancienne (telle que Cygwin , qui inclut git et bien plus encore, ou GNUwin32 , qui manque de git mais na pas le mauvais-employé-essayant-dutiliser-linux -but-we-impos-windows que donne Cygwin). Cette fonctionnalité a été ajoutée dans la version 4.2.12, il y a plus de 9 ans (cétait la dernière fonctionnalité identifiée à faire GNU find Compatible POSIX).

Si vous souhaitez vous en tenir à une ancienne recherche GNU, vous pouvez utiliser -print0 avec xargs -0 pour obtenir une fonctionnalité similaire: exécution de commandes groupées, prenant en charge les noms de fichiers arbitraires.

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

Citez toujours les caractères génériques sur find ligne de commande. Sinon, si vous exécutez cette commande à partir dun répertoire contenant des fichiers .c, les fichiers *.c sans guillemets d être étendu à la liste des fichiers .c dans le répertoire actuel.

Ajout de /dev/null au grep la ligne de commande est une astuce pour sassurer que grep affichera toujours le nom du fichier, même si find trouve une seule correspondance. Avec GNU find, une autre méthode consiste à passer loption -H.

Commentaires

  • Que faites-vous signifie par mauvais-employé-essayant-dutiliser-linux-mais-nous-imposons-la vibration que donne cygwin?
  • GNUwin32 ne ‘ pas 🙁
  • Voir mes commentaires sur la question.
  • Les guillemets autour du semi ont fonctionné à partir dun script package.json.

Réponse

Si une commande telle que

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

renvoie une erreur

find: missing argument to -exec 

la cause probable est trop ancienne GNU find qui ne prend pas en charge la syntaxe -exec mycommand {} +. Dans ce cas, le remplacement de faibles performances consiste à exécuter -exec mycommand {} \; qui exécutera mycommand une fois pour chaque cible trouvée au lieu de collecter plusieurs cibles et exécuter le mycommand une seule fois.

Cependant, GNU find doe ne prend pas en charge par exemple

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

car GNU find ne prend en charge que les combinaisons littérales {} + au lieu de {} additional parameters + plus génériques. Notez quil ne peut rien y avoir entre les accolades et le caractère +. Si vous essayez ceci, vous obtiendrez la même erreur:

find: missing argument to -exec 

La solution de contournement consiste à utiliser la syntaxe {} additional parameters \; qui fonctionne mais exécutera la commande une fois pour chaque cible trouvée. Si vous avez besoin de plus de performances avec GNU find, vous devez écrire un script wrapper qui peut ajouter des paramètres supplémentaires aux arguments donnés. Quelque chose comme

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

devrait suffire. Ou, si vous ne souhaitez pas créer de fichier temporaire, vous pouvez utiliser une ligne pour changer lordre des paramètres comme celui-ci:

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

qui exécutera mycommand {list of ttf files} extra arguments. Notez que vous devrez peut-être doubler les caractères spéciaux déchappement pour le bash après lindicateur -c.

Commentaires

  • (1) La partie de ce qui précède qui répond réellement à la question a déjà été donnée par dautres personnes. (2) Ce que vous décrivez nest pas une faille ou une carence dans GNU find, mais le comportement correct spécifié par POSIX .
  • +1 Enfin, quelquun qui répond pourquoi les paramètres supplémentaires ne fonctionnent pas ‘! Cela semble être une lacune dans la définition POSIX.
  • Si vous ‘ vous GNU find vous ‘ jai probablement GNU cp. Dans ce cas, vous pouvez find ... -exec cp --target-directory ~/.fonts {} + conserver le {} à la fin de la chaîne dexécution.

Réponse

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

a obtenu une erreur find: missing argument to ``-exec".

Lajout despace entre {} et \ a corrigé le problème:

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

Commentaires

  • Ce problème nexiste pas dans le find dans la question en question.
  • Dans Question ce nest pas, très bien, que jai compris, mais le problème est le même  » find: argument manquant à «  -exec ‘ « , Le problème peut survenir pour une raison différente-2, jai répondu parce que jai vu la même déclaration de problème.
  • @Kusalananda bon chagrin, le noob a fourni une solution à lerreur signalée qui est indiquée par le PO dans le titre et le corps de la question.
  • @bvj La question traite explicitement avec la forme + de loption -exec à find. Cette réponse corrige un problème que lutilisateur qui pose la question na pas.

Réponse

Jai eu mon part de maux de tête avec la syntaxe exec dans le passé. la plupart du temps maintenant, je préfère la meilleure syntaxe bash:

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

Il y a quelques limitations lorsque vous voulez traiter les fichiers comme un groupe, car chacun est évalué en série, mais vous pouvez diriger la sortie ailleurs très bien

Commentaires

  • Bien que cela ait tendance à fonctionner, il est nettement moins utile que la version pure-find car elle ne peut pas gérer correctement les fichiers avec des espaces dans le nom.
  • Non, ‘ ne faites pas cela. Cela sarrête dès que les fichiers contiennent des espaces et dautres caractères «bizarres». Cest également plus complexe et plus lent que find … -exec … \;, donc il ny a ‘ aucune raison de lutiliser même si vous savez que vos noms de fichiers sont apprivoiser.
  • cela a été utile dans ma situation où je devais exécuter plusieurs lignes de logique basées sur les noms de fichiers (comme supprimer des caractères, créer des répertoires, puis déplacer les fichiers). Essayer dobtenir find pour faire plusieurs choses en un seul exec était trop difficile pour les 5 minutes que je voulais y consacrer. Mes noms de fichiers étaient apprivoisés et cela a résolu mon problème 🙂

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *