sed
Substitution
Recherche…
Substitution à l'aide de variables shell
Variables à l' intérieur des guillemets simples '
ne sont pas compatibles par des obus étendus POSIX, donc en utilisant une variable shell dans une sed
substitution nécessite l'utilisation de guillemets doubles "
au lieu de guillemets simples '
:
$ var="he"
$ echo "hello" | sed "s/$var/XX/"
XXllo
$ var="he"
$ echo "hello" | sed 's/$var/XX/'
hello
Attention à l'injection de commande lors de l'évaluation des variables:
$ var='./&/;x;w/etc/passwd
> x;s/he'
$ echo "hello" | sed "s/$var/XX/"
sed: /etc/passwd: Permission denied
Si ce qui précède était exécuté en tant que root, la sortie aurait été impossible à distinguer du premier exemple, et le contenu de /etc/passwd
serait détruit.
Backreference
En utilisant des parenthèses échappées, vous pouvez définir un groupe de capture dans un modèle pouvant être référencé dans la chaîne de substitution avec \1
:
$ echo Hello world! | sed 's/\(Hello\) world!/\1 sed/'
Hello sed
Avec plusieurs groupes:
$ echo one two three | sed 's/\(one\) \(two\) \(three\)/\3 \2 \1/'
three two one
Lorsque vous utilisez des expressions régulières étendues (voir Options supplémentaires ), les parenthèses effectuent un regroupement par défaut et ne doivent pas être échappées:
$ echo one two three | sed -E 's/(one) (two) (three)/\3 \2 \1/'
three two one
Les mots composés de lettres, de chiffres et de traits de soulignement peuvent être comparés à l'aide de l'expression [[:alnum:]_]\{1,\}
:
$ echo Hello 123 reg_exp | sed 's/\([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\)/\3 \2 \1/'
reg_exp 123 Hello
La séquence \w
est équivalente à [[:alnum:]_]
$ echo Hello 123 reg_exp | sed 's/\(\w\w*\) \(\w\w*\) \(\w\w*\)/\3 \2 \1/'
reg_exp 123 Hello
Utiliser différents délimiteurs
La spécification de base Open Group POSIX / IEEE indique :
[2addr] s / BRE / remplacement / flags
Remplacez la chaîne de remplacement pour les instances du BRE dans l'espace objet. Tout caractère autre que la barre oblique inverse ou la nouvelle ligne peut être utilisé à la place d'une barre oblique pour délimiter le BRE et le remplacement. Dans le BRE et le remplacement, le délimiteur BRE lui-même peut être utilisé comme un caractère littéral s'il est précédé d'une barre oblique inverse.
Il y a des cas où le remplacement du séparateur /
for sed
trouve dans le BRE ou le remplacement, ce qui déclenche des erreurs telles que:
$ echo "2/3/4" | sed "s/2/3/X/"
sed: -e expression #1, char 7: unknown option to `s'
Pour cela, nous pouvons utiliser différents délimiteurs tels que #
ou _
ou même un espace:
$ echo "2/3/4" | sed "s#2/3#X#"
X/4
$ echo "2/3/4" | sed "s_2/3_X_"
X/4
$ echo "2/3/4" | sed "s 2/3 X "
X/4
Indicateurs de modèle - remplacement d'occurrence
Si nous voulons remplacer uniquement la première occurrence d'une ligne, nous utilisons sed
comme d'habitude:
$ cat example
aaaaabbbbb
aaaaaccccc
aaaaaddddd
$ sed 's/a/x/' example
xaaaabbbbb
xaaaaccccc
xaaaaddddd
Mais que faire si nous voulons remplacer toutes les occurrences?
Nous ajoutons simplement le drapeau g
pattern à la fin:
$ sed 's/a/x/g' example
xxxxxbbbbb
xxxxxccccc
xxxxxddddd
Et si nous voulons remplacer une occurrence spécifique, nous pouvons effectivement spécifier laquelle:
$ sed 's/a/x/3' example
aaxaabbbbb
aaxaaccccc
aaxaaddddd
/3
étant la 3ème occurrence.
À partir de info sed
, consultez le manuel GNU sed pour la version en ligne
Le standard POSIX ne spécifie pas ce qui doit se passer lorsque vous mélangez les modificateurs
g
et NUMBER. Actuellement, il n’ya pas de consensus sur les implémentationssed
. Pour GNUsed
, l'interaction est définie comme suit: ignorer les correspondances avant le NUMBERth, puis faire correspondre et remplacer toutes les correspondances de NUMBERth.
$ sed 's/b/y/2g' example
aaaaabyyyy
aaaaaccccc
aaaaaddddd
$ sed 's/c/z/g3' example
aaaaabbbbb
aaaaacczzz
aaaaaddddd