find & sed (rechercher et remplacer)

27

J'utilise la commande suivante sur mon mac:

$find . -name “*.java” -exec sed -i ’s/foo/bar/g’ {} \;

et cela semble n'avoir aucun effet.

J'ai deux fichiers dans le répertoire qui se terminent par .java, qui contiennent tous les deux le texte foo. Suis-je en train de manquer quelque chose?

EDIT: Résultats de la demande de commentaires

[aafghani-03:~/test amirafghani]$ find . -name "*.java" -exec sed -i 's/foo/bar/g' {} \;
sed: 1: "./bar.java": invalid command code .
sed: 1: "./foo.java": invalid command code .
Amir Afghani
la source
2
Est-ce exactement ce que vous exécutez? Et si vous supprimez le -execet tout ce qui se trouve après? Imprime-t-il les noms des fichiers Java? (Je crains que vous n'utilisiez des guillemets intelligents au lieu de guillemets ASCII.)
Mikel
1
En fait, cela résout le problème, du moins pour moi. Les guillemets simples et doubles doivent être remplacés respectivement par "et '.
Lev Levitsky
2
Citations intelligentes (?)! .. :)
Peter.O
Ce que j'ai collé était exactement ce que je courais. Quelqu'un peut-il poster une réponse?
Amir Afghani
1
La prochaine fois, veuillez publier le message d'erreur que vous voyez lorsque vous posez la question. Cela fera gagner du temps à tout le monde.
Mikel

Réponses:

34

Tout d'abord, assurez-vous que vous utilisez des guillemets ascii réguliers comme "et '(codes ascii 0x22et 0x27, respectivement) dans les scripts shell, car l'exemple de votre message contient des guillemets non standard. Si vous regardez attentivement, ils ont l'air un peu différents. Il s'agit très probablement d'une erreur de copier-coller à partir d'un format de document texte riche comme Word, OOWriter ou même une fenêtre de navigateur.

Puisque vous êtes sur un Mac, vous avez probablement l'implémentation de FreeBSD sed, auquel cas vous devez écrire la commande de cette façon:

find . -name "*.java" -exec sed -i '' s/foo/bar/g {} +

(ici en utilisant +au lieu de \;pour éviter d'exécuter une sedinvocation par fichier).

Dans l'implémentation de FreeBSD, sedl' -iindicateur a besoin d'un argument: l'extension d'un fichier de sauvegarde. Par exemple, -i .bakla commande sauvegardera file1.txten file1.txt.bakpremier avant d'effectuer le remplacement dans le fichier d'origine. L'utilisation d'un argument vide ''signifie de ne pas utiliser de fichier de sauvegarde, ce qui semble être ce que vous voulez.

La même chose dans l'implémentation GNU (ou NetBSD, OpenBSD, busybox) serait:

find . -name "*.java" -exec sed -i s/foo/bar/g {} +

Merci @bahamat et @Mikel et @ pieter-race d' avoir amélioré ma réponse avec vos commentaires.

janos
la source
Que font les accolades bouclées?
Zane Hitchcox
3
@ZaneHitchcox les accolades sont des espaces réservés pour le nom de fichier correspondant
janos