Il n'y a aucun moyen de le faire en utilisant uniquement sed. Vous devrez utiliser au moins l'utilitaire de recherche ensemble :
find . -type f -exec sed -i.bak "s/foo/bar/g" {} \;
Cette commande créera un .bak fichier pour chaque fichier modifié.
Remarques :
- Le
-iargument poursedcommand est une extension GNU, donc, si vous exécutez cette commande avec lesedde BSD vous devrez rediriger la sortie vers un nouveau fichier puis le renommer. - Le
findl'utilitaire n'implémente pas le-execargument dans les anciennes boîtes UNIX, vous devrez donc utiliser un| xargsà la place.
Je préfère utiliser find | xargs cmd supérieur à find -exec parce que c'est plus facile à retenir.
Cet exemple remplace globalement "foo" par "bar" dans les fichiers .txt au niveau ou en dessous de votre répertoire actuel :
find . -type f -name "*.txt" -print0 | xargs -0 sed -i "s/foo/bar/g"
Le -print0 et -0 les options peuvent être omises si vos noms de fichiers ne contiennent pas de caractères funky tels que des espaces.
Pour la portabilité, je ne compte pas sur les fonctionnalités de sed spécifiques à Linux ou BSD. Au lieu de cela, j'utilise le overwrite script du livre de Kernighan et Pike sur l'environnement de programmation Unix.
La commande est alors
find /the/folder -type f -exec overwrite '{}' sed 's/old/new/g' {} ';'
Et le overwrite script (que j'utilise partout) est
#!/bin/sh
# overwrite: copy standard input to output after EOF
# (final version)
# set -x
case $# in
0|1) echo 'Usage: overwrite file cmd [args]' 1>&2; exit 2
esac
file=$1; shift
new=/tmp/$$.new; old=/tmp/$$.old
trap 'rm -f $new; exit 1' 1 2 15 # clean up files
if "[email protected]" >$new # collect input
then
cp $file $old # save original file
trap 'trap "" 1 2 15; cp $old $file # ignore signals
rm -f $new $old; exit 1' 1 2 15 # during restore
cp $new $file
else
echo "overwrite: $1 failed, $file unchanged" 1>&2
exit 1
fi
rm -f $new $old
L'idée est qu'il écrase un fichier uniquement si une commande réussit. Utile en find et aussi où vous ne voudriez pas utiliser
sed 's/old/new/g' file > file # THIS CODE DOES NOT WORK
car le shell tronque le fichier avant sed peut le lire.