C'est une vieille question, mais aucune des réponses ici ne traite des opérations autrement qu'en s/from/to/
détail.
La forme générale d'une sed
déclaration est
*address* *action*
où l' adresse peut être une plage de regex ou une plage de numéros de ligne (ou vide, auquel cas l' action est appliquée à chaque ligne d'entrée). Donc par exemple
sed '1,4d' file
supprimera les lignes 1 à 4 (l' adresse est la plage de numéros de ligne 1,4
et l' action est la d
commande de suppression); et
sed '/ick/,$s/foo/bar/' file
remplacera la première occurrence de foo
par bar
sur n'importe quelle ligne entre la première correspondance sur l'expression régulière ick
et la fin du fichier (l' adresse est la plage /ick/,$
et l' action est la s
commande de substitutions/foo/bar/
).
Dans ce contexte, s'il ick
provenait d'une variable, vous pourriez faire
sed "/$variable/,\$s/foo/bar/"
(notez l'utilisation de guillemets doubles au lieu de simples, afin que le shell puisse interpoler la variable, et la nécessité de citer le signe dollar littéral entre guillemets doubles) mais si la variable contient une barre oblique, vous obtiendrez une erreur de syntaxe. (Le shell développe la variable, puis passe la chaîne résultante à sed
; donc sed
ne voit que le texte littéral - il n'a pas de concept des variables du shell.)
Le remède consiste à utiliser un délimiteur différent (où vous devez évidemment pouvoir utiliser un caractère qui ne peut pas apparaître dans la valeur de la variable), mais contrairement au s%foo%bar%
cas, vous avez également besoin d'une barre oblique inverse avant le délimiteur si vous souhaitez utiliser un autre délimiteur que la valeur par défaut /
:
sed "\\%$variable%,\$s/foo/bar/" file
(entre guillemets simples, une seule barre oblique inverse suffirait évidemment); ou vous pouvez échapper séparément chaque barre oblique de la valeur. Cette syntaxe particulière est uniquement Bash:
sed "/${variable//\//\\/}/,\$s/foo/bar/" file
ou si vous utilisez un autre shell, essayez
escaped=$(echo "$variable" | sed 's%/%\\/%g')
sed "s/$escaped/,\$s/foo/bar/" file
Pour plus de clarté, si $variable
la chaîne contenait la chaîne, 1/2
les commandes ci-dessus seraient équivalentes à
sed '\%1/2%,$s/foo/bar/' file
dans le premier cas, et
sed '/1\/2/,$s/foo/bar/' file
dans la seconde.