Comment passer une variable contenant des barres obliques comme motif à sed
?
Par exemple, si j'ai la variable suivante:
var="/Users/Documents/name/file"
Je veux le transmettre sed
comme tel:
sed "s/$var/replace/g" "$file"
Cependant, j'obtiens des erreurs. Comment puis-je contourner le problème?
$var
Une réponse pure bash: utilisez l' expansion des paramètres pour échapper à la barre oblique inverse des barres obliques dans la variable:
la source
${parameter/pattern/string}
. Donc, dans ce cas, le paramètre estvar
, le modèle est/\/
et la chaîne est\\/
. Toutes les instances du modèle sont remplacées car le modèle commence par un/
.Une autre façon de le faire, bien que plus moche que la réponse d'anubhava, consiste à échapper toutes les barres obliques inverses en
var
utilisant une autresed
commande:alors, cela fonctionnera:
la source
L'utilisation de
/
in sed comme délimiteur entrera en conflit avec les barres obliques de la variable lorsqu'elle sera remplacée et, par conséquent, vous obtiendrez une erreur. Une façon de contourner ce problème consiste à utiliser un autre délimiteur unique parmi tous les caractères de cette variable.vous pouvez utiliser le caractère octothorpe qui convient à l'occasion (ou tout autre caractère qui n'est pas un
/
pour la facilité d'utilisation)ou
cela convient lorsque la variable ne contient pas d'espaces
ou
Il est plus sage d'utiliser ce qui précède car nous sommes intéressés à substituer ce qui se trouve dans cette variable uniquement par rapport à la double citation de la commande entière, ce qui peut amener votre shell à interpréter tout caractère qui pourrait être considéré comme un caractère spécial du shell.
la source
$var
contient~
, vous devrez évidemment choisir un autre délimiteur. L'erreur "non terminée" sonne comme si votre$var
contenait une nouvelle ligne; vous pourrez peut-être le réparer en échappant à chaque nouvelle ligne dans la valeur, mais je ne pense pas que ce soit entièrement portable. Cela n'a généralement aucun rapport avec le problème des barres obliques dans la valeur.sed -i "s~blah~$var~g" file
avec des guillemets uniquement autour dused
script réel .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 estoù 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
supprimera les lignes 1 à 4 (l' adresse est la plage de numéros de ligne
1,4
et l' action est lad
commande de suppression); etremplacera la première occurrence de
foo
parbar
sur n'importe quelle ligne entre la première correspondance sur l'expression régulièreick
et la fin du fichier (l' adresse est la plage/ick/,$
et l' action est las
commande de substitutions/foo/bar/
).Dans ce contexte, s'il
ick
provenait d'une variable, vous pourriez faire(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
; doncsed
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/
:(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:
ou si vous utilisez un autre shell, essayez
Pour plus de clarté, si
$variable
la chaîne contenait la chaîne,1/2
les commandes ci-dessus seraient équivalentes àdans le premier cas, et
dans la seconde.
la source
Utilisez Perl, où les variables sont des citoyens de première classe, pas seulement des macros en expansion:
-p
lit l'entrée ligne par ligne et imprime la ligne après traitement\Q
cite tous les métacaractères dans la chaîne suivante (non nécessaire pour la valeur présentée ici, mais nécessaire si la valeur contenue[
ou certaines autres valeurs spéciales pour les expressions régulières)la source