J'ai "J'aime Suzi et Marry" et je veux changer "Suzi" en "Sara".
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
Le résultat doit être comme ça:
firstString="I love Sara and Marry"
Pour remplacer la première première occurrence d'un modèle par une chaîne donnée, utilisez ${parameter/pattern/string}
:
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/$secondString}"
# prints 'I love Sara and Marry'
Pour remplacer toutes les occurrences , utilisez ${parameter//pattern/string}
:
message='The secret code is 12345'
echo "${message//[0-9]/X}"
# prints 'The secret code is XXXXX'
(Ceci est documenté dans le Manuel de référence Bash , §3.5.3 "Développement des paramètres du shell" .)
Notez que cette fonctionnalité n'est pas spécifiée par POSIX - c'est une extension Bash - donc tous les shells Unix ne l'implémentent pas. Pour la documentation POSIX pertinente, voir Spécifications de base de la norme technique du groupe Open, numéro 7 , le Shell & Utilities volume, §2.6.2 "Extension des paramètres" .
Cela peut être fait entièrement avec la manipulation de chaîne bash:
first="I love Suzy and Mary"
second="Sara"
first=${first/Suzy/$second}
Cela remplacera seulement la première occurrence; pour les remplacer tous, doublez la première barre oblique:
first="Suzy, Suzy, Suzy"
second="Sara"
first=${first//Suzy/$second}
# first is now "Sara, Sara, Sara"
essaye ça:
sed "s/Suzi/$secondString/g" <<<"$firstString"
Pour Dash, tous les posts précédents ne fonctionnent pas
La solution compatible POSIX sh
est:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
Il vaut mieux utiliser bash que sed
si les chaînes ont des caractères RegExp.
echo ${first_string/Suzi/$second_string}
Il est portable pour Windows et fonctionne avec au moins le même âge que Bash 3.1.
Pour montrer que vous n'avez pas à vous soucier de votre échappatoire, tournons-nous à ceci:
/home/name/foo/bar
Dans ceci:
~/foo/bar
Mais seulement si /home/name
est au début. Nous n'avons pas besoin de sed
!
Etant donné que bash nous donne les variables magiques $PWD
et $HOME
, nous pouvons:
echo "${PWD/#$HOME/\~}"
EDIT: Merci à Mark Haferkamp dans les commentaires de la note citant/échappant ~
. *
Notez que la variable $HOME
contient des barres obliques sans que rien ne se casse.
Pour en savoir plus: Advanced Bash-Scripting Guide .
Si vous devez utiliser sed
, assurez-vous de échappe tous les caractères .
Si demain vous décidez que vous n'aimez pas Marry, elle peut également être remplacée:
today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt
Il doit y avoir 50 façons de quitter votre amoureux.
Depuis je ne peux pas ajouter de commentaire. @ruaka Pour rendre l'exemple plus lisible, écrivez-le comme ceci
full_string="I love Suzy and Mary"
search_string="Suzy"
replace_string="Sara"
my_string=${full_string/$search_string/$replace_string}
or
my_string=${full_string/Suzy/Sarah}
Pure POSIX Méthode Shell, qui contrairement à réponse de --- (la réponse de Roman Kazanovskyi de sed
- ) == n'a besoin d'aucun outil externe, mais uniquement du natif de Shell - extensions de paramètres . Notez que les noms de fichier longs sont minimisés afin que le code tienne mieux sur une seule ligne:
_f="I love Suzi and Marry"
s=Sara
t=Suzi
[ "${f%$t*}" != "$f" ] && f="${f%$t*}$s${f#*$t}"
echo "$f"
_
Sortie:
_I love Sara and Marry
_
Comment ça fonctionne:
Supprimer le plus petit modèle de suffixe. _"${f%$t*}"
_ renvoie "I love
" si le suffixe _$t
_ "Suzi*
" est in _$f
_ " I love
Suzi and Marry
".
Mais si _t=Zelda
_, alors _"${f%$t*}"
_ ne supprime rien et renvoie la chaîne complète "I love Suzi and Marry
".
Ceci est utilisé pour tester si _$t
_ est dans _$f
_ avec _[ "${f%$t*}" != "$f" ]
_ qui sera évalué à true si la chaîne _$f
_ contient "Suzi*
"et false sinon.
Si le test renvoie true, créez la chaîne souhaitée à l'aide de Supprimer le plus petit modèle de suffixe _${f%$t*}
_ "I love
" et - Supprimer le plus petit modèle de préfixe _${f#*$t}
_ "and Marry
", avec le 2nd chaîne _$s
_ "Sara
"entre les deux.