J'utilise ce qui suit pour rechercher récursivement un répertoire dans une chaîne et le remplacer par un autre:
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g'
Cela fonctionne bien. Le seul problème est que si la chaîne n'existe pas, alors sed
échoue car il ne reçoit aucun argument. C'est un problème pour moi puisque j'exécute ceci automatiquement avec ANT et que la construction échoue puisque sed
échoue.
Y a-t-il un moyen de le rendre infaillible au cas où la chaîne ne serait pas trouvée?
Je suis intéressé par une solution simple à une ligne que je peux utiliser (pas nécessairement avec grep
ou sed
mais avec des commandes unix communes comme celles-ci).
Vous pouvez utiliser find
et -exec
directement dans sed
plutôt que de localiser d'abord oldstr
avec grep
. C'est peut-être un peu moins efficace, mais ce n'est peut-être pas important. De cette façon, le remplacement sed
est exécuté sur tous les fichiers répertoriés par find
, mais si oldstr
ne figure pas dans ce répertoire, il ne fonctionnera évidemment pas.
find /path -type f -exec sed -i 's/oldstr/newstr/g' {} \;
Votre solution est ok. essayez seulement de cette façon:
files=$(grep -rl oldstr path) && echo $files | xargs sed....
alors exécutez le xargs
uniquement lorsque grep renvoie 0
, par exemple. quand trouvé la chaîne dans certains fichiers.
J'ai pris l'idée de Vlad et l'ai modifiée un peu. Au lieu de
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' /dev/null
Quels rendements
sed: couldn't edit /dev/null: not a regular file
Je fais dans 3 connexions différentes au serveur distant
touch deleteme
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' ./deleteme
rm deleteme
Bien que cela soit moins élégant et nécessite 2 connexions supplémentaires sur le serveur (il y a peut-être un moyen de tout faire en une seule ligne), il fait aussi le travail efficacement
La norme xargs
ne dispose d'aucun moyen efficace. vous feriez mieux d'utiliser find -exec
comme quelqu'un l’a suggéré, ou enveloppez le sed
dans un script qui ne fait rien s’il n’ya pas d’argument. GNU xargs
a le --no-run-if-empty
Option et BSD/OS X xargs
a le -L
option qui semble devoir faire quelque chose de similaire.
Je pense que sans utiliser -exec
vous pouvez simplement fournir /dev/null
comme au moins un argument au cas où rien ne serait trouvé:
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' /dev/null
Mon cas d'utilisation était que je voulais remplacer foo:/Drive_Letter
avec foo:/bar/baz/xyz
Dans mon cas, j'ai pu le faire avec le code suivant. J'étais dans le même répertoire que celui où se trouvaient la plupart des fichiers.
find . -name "*.library" -print0 | xargs -0 sed -i '' -e 's/foo:\/Drive_Letter:/foo:\/bar\/baz\/xyz/g'
espérons que cela a aidé.