J'ai utilisé avec succès la commande sed
suivante pour rechercher/remplacer du texte sous Linux:
sed -i 's/old_link/new_link/g' *
Cependant, lorsque je l'essaie sur mon Mac OS X, je reçois:
"la commande c attend\suivi d'un texte"
Je pensais que mon Mac fonctionnait sous BASH Shell. Quoi de neuf?
MODIFIER:
Selon @High Performance, cela est dû au fait que Mac sed
a une saveur différente (BSD). Ma question est donc de savoir comment répliquer cette commande dans BSD sed
.
MODIFIER:
Voici un exemple concret qui provoque ceci:
sed -i 's/hello/gbye/g' *
Si vous utilisez l'option -i, vous devez fournir une extension pour vos sauvegardes.
Si tu as:
File1.txt
File2.cfg
La commande (notez le manque d’espace entre -i
et ''
et le -e
pour que cela fonctionne avec les nouvelles versions de Mac et GNU):
sed -i'.original' -e 's/old_link/new_link/g' *
créer 2 fichiers de sauvegarde comme:
File1.txt.original
File2.cfg.original
Il n'y a pas de moyen portable d'éviter de créer des fichiers de sauvegarde car il est impossible de trouver un mélange de commandes sed qui fonctionne dans tous les cas:
sed -i -e ...
- ne fonctionne pas sous OS X car il crée des sauvegardes -e
sed -i'' -e ...
- ne fonctionne pas sous OS X 10.6 mais fonctionne sous 10.9+sed -i '' -e ...
- ne fonctionne pas sous GNUNote Etant donné qu'aucune commande sed ne fonctionne sur toutes les plateformes, vous pouvez essayer d'utiliser une autre commande pour obtenir le même résultat.
par exemple. Perl -i -pe's/old_link/new_link/g' *
Je pense que sur OS X, lorsque vous utilisez -i, une extension des fichiers de sauvegarde est obligatoire . Essayer:
sed -i .bak 's/hello/gbye/g' *
Avec GNU sed
, l’extension est optionnel .
Cela fonctionne avec les versions GNU et BSD de sed:
sed -i'' -e 's/old_link/new_link/g' *
ou avec sauvegarde:
sed -i'.bak' -e 's/old_link/new_link/g' *
Notez l'espace manquant après l'option -i
! (Nécessaire pour GNU sed)
Avait le même problème dans Mac et résolu avec brew
:
brew install gnu-sed
et utiliser comme
gsed SED_COMMAND
vous pouvez également définir sed
comme alias sur gsed
(si vous le souhaitez):
alias sed=gsed
Vous pouvez également installer la version GNU de sed sur votre Mac, appelée gsed, et l’utiliser à l’aide de la syntaxe Linux standard.
Pour cela, installez gsed
en utilisant les ports (si vous ne l’avez pas, procurez-vous à http://www.macports.org/ ) en exécutant Sudo port install gsed
. Ensuite, vous pouvez exécuter sed -i 's/old_link/new_link/g' *
La réponse de Sinetris est correcte, mais j'utilise la commande find
pour préciser les fichiers à modifier. En général, cela devrait fonctionner (testé sur osx /bin/bash
):
find . -name "*.smth" -exec sed -i '' 's/text1/text2/g' {} \;
En général, utiliser sed
sans find
dans des projets complexes est moins efficace.
Votre Mac utilise effectivement un shell BASH, mais la question de la mise en œuvre de sed que vous utilisez est une question. Sur un Mac, sed provient de BSD et est légèrement différent de celui que vous pourriez trouver sur une machine Linux typique. Je vous suggère man sed
.
Voici comment appliquer des variables d’environnement au fichier de modèle (aucune sauvegarde requise).
echo "Hello {{FOO}}" > foo.conf.tmpl
FOO="world" && sed -e "s/{{FOO}}/$FOO/g" foo.conf.tmpl > foo.conf
Travailler à la fois macOS 10.12.4 et Ubuntu 14.04.5
sed -ie 's/old_link/new_link/g' *
Fonctionne sur BSD et Linux
Comme l’indiquent les autres réponses, il n’existe pas de moyen d’utiliser Sed sur OS X et Linux sans créer de fichiers de sauvegarde. J'ai donc utilisé à la place cette doublure Ruby:
Ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml
Dans mon cas, je devais l'appeler à partir d'une tâche rake
(c'est-à-dire à l'intérieur d'un script Ruby). J'ai donc utilisé ce niveau supplémentaire de citation:
sh %q{Ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml}
J'ai créé une fonction permettant de gérer la différence sed
entre MacOS (testé sous MacOS 10.12) et un autre système d'exploitation:
OS=`uname`
# $(replace_in_file pattern file)
function replace_in_file() {
if [ "$OS" = 'Darwin' ]; then
# for MacOS
sed -i '' -e "$1" "$2"
else
# for Linux and Windows
sed -i'' -e "$1" "$2"
fi
}
Usage:
$(replace_in_file 's,MASTER_Host.*,MASTER_Host='"$MASTER_IP"',' "./mysql/.env")
Où:
,
est un délimètre
's,MASTER_Host.*,MASTER_Host='"$MASTER_IP"','
est un motif
"./mysql/.env"
est le chemin du fichier