web-dev-qa-db-fra.com

Comment échapper aux guillemets simples et doubles dans sed?

D'après ce que je peux trouver, lorsque vous utilisez des guillemets simples, tout ce qui est à l'intérieur est considéré comme littéral. Je le veux pour ma substitution. Mais je veux aussi trouver une chaîne qui a des guillemets simples ou doubles.

Par exemple, 

sed -i 's/"http://www.fubar.com"/URL_FUBAR/g'

Je souhaite remplacer "http://www.fubar.com" par "URL_FUBAR". Comment sed est-il censé reconnaître mes // ou mes guillemets?

Merci pour toute aide!

EDIT: Puis-je utiliser s/\"http\:\/\/www\.fubar\.\com\"/URL_FUBAR/g?

Est-ce que\échappe réellement aux caractères entre guillemets simples?

57
KRB

La commande sed vous permet d'utiliser d'autres caractères au lieu de / comme délimiteur dans sa commande s:

sed 's#"http://www\.fubar\.com"#URL_FUBAR#g'

Les guillemets ne sont pas un problème. Pour faire correspondre les guillemets simples, basculez les deux types de guillemets. Notez qu'une seule chaîne entre guillemets peut ne pas contenir de guillemets simples (même pas des guillemets).

Les points doivent être évités si sed doit les interpréter en tant que points et non en tant que motif d'expression régulière . qui correspond à n'importe quel caractère.

70
Kusalananda

En ce qui concerne le guillemet simple, voir le code ci-dessous utilisé pour remplacer la chaîne let's par let us:

commander:

echo "hello, let's go"|sed 's/let'"'"'s/let us/g'

résultat:

bonjour, partons

21
tony duan

Il est difficile d'échapper à une citation unique entre guillemets simples. Essaye ça:

sed "s@['\"]http://www.\([^.]\+).com['\"]@URL_\U\1@g" 

Exemple:

$ sed "s@['\"]http://www.\([^.]\+\).com['\"]@URL_\U\1@g" <<END
this is "http://www.fubar.com" and 'http://www.example.com' here
END

produit

this is URL_FUBAR and URL_EXAMPLE here
10
glenn jackman

Mon problème était que je devais avoir le "" en dehors de l'expression car j'ai une variable dynamique à l'intérieur de l'expression sed elle-même. Donc, la solution actuelle est celle de Lenn Jackman que vous remplacez le " dans la regex sed par [\"]

Donc, mon bash complet est:

RELEASE_VERSION="0.6.6"

sed -i -e "s#value=[\"]trunk[\"]#value=\"tags/$RELEASE_VERSION\"#g" myfile.xml

Voici:

# est le séparateur sed

[\"] = " en regex

valeur = \"tags/$RELEASE_VERSION\" = ma chaîne de remplacement, il est important qu'il ne contienne que le \" pour les guillemets

8
Denis

Échapper à un guillemet double peut être absolument nécessaire dans sed: par exemple, si vous utilisez des guillemets dans toute l'expression sed (comme vous devez le faire lorsque vous souhaitez utiliser une variable Shell).

Voici un exemple qui évite de s’échapper dans sed, mais qui capture également quelques problèmes de citation dans bash:

# cat inventory
PURCHASED="2014-09-01"
SITE="Atlanta"
LOCATION="Room 154"

Supposons que vous vouliez changer de pièce à l'aide d'un script sed que vous pouvez utiliser encore et encore. Vous pouvez donc modifier l'entrée comme suit:

# i="Room 101" (these quotes are there so the variable can contains spaces)

Ce script ajoutera la ligne entière s'il n'y en a pas, ou remplacera simplement (en utilisant sed) la ligne qui se trouve là avec le texte plus la valeur de $ i. 

if grep -q LOCATION inventory; then 
## The sed expression is double quoted to allow for variable expansion; 
## the literal quotes are both escaped with \ 
    sed -i "/^LOCATION/c\LOCATION=\"$i\"" inventory
## Note the three layers of quotes to get echo to expand the variable
## AND insert the literal quotes
else 
    echo LOCATION='"'$i'"' >> inventory
fi

P.S. J'ai écrit le script ci-dessus sur plusieurs lignes pour que les commentaires soient analysables, mais je l'utilise comme une ligne sur la ligne de commande qui ressemble à ceci: 

i="your location"; if grep -q LOCATION inventory; then sed -i "/^LOCATION/c\LOCATION=\"$i\"" inventory; else echo LOCATION='"'$i'"' >> inventory; fi
1

De plus, les expressions sed contenant des variables BASH doivent être doubles (") - entre guillemets pour que la variable soit interprétée correctement.

Si vous aussi double-citez votre variable $ BASH (pratique recommandée)

... alors vous pouvez échapper aux guillemets variables comme indiqué:

sed -i "s/foo/bar ""$VARIABLE""/g" <file>

Autrement dit, remplacez le " associé à $ VARIABLE par "".

(Simplement -écaper "$VAR" en tant que \"$VAR\" donne une chaîne de sortie citée "-.)


Exemples

$ VAR='apples and bananas'
$ echo $VAR
apples and bananas

$ echo "$VAR"
apples and bananas

$ printf 'I like %s!\n' $VAR
I like apples!
I like and!
I like bananas!

$ printf 'I like %s!\n' "$VAR"
I like apples and bananas!

Ici, $ VAR est "- cité avant de passer à sed (sed est soit '-, soit "- cité):

$ printf 'I like %s!\n' "$VAR" | sed 's/$VAR/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed 's/"$VAR"/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed 's/$VAR/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed 's/""$VAR""/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed "s/$VAR/cherries/g"
I like cherries!

$ printf 'I like %s!\n' "$VAR" | sed "s/""$VAR""/cherries/g"
I like cherries!

Comparez cela à:

$ printf 'I like %s!\n' $VAR | sed "s/$VAR/cherries/g"
I like apples!
I like and!
I like bananas!


$ printf 'I like %s!\n' $VAR | sed "s/""$VAR""/cherries/g"
I like apples!
I like and!
I like bananas!

... etc ...

Conclusion

Ma recommandation, comme pratique courante, est de

  • "- citer les variables BASH ("$VAR")
  • "- quote, encore, ces variables (""$VAR"") si elles sont utilisées dans une expression sed (qui doit elle-même être "- quoted, pas '- quoted)
$ VAR='apples and bananas'

$ echo "$VAR"
apples and bananas

$ printf 'I like %s!\n' "$VAR" | sed "s/""$VAR""/cherries/g"
I like cherries!

0
Victoria Stuart
Prompt% cat t1
This is "Unix"
This is "Unix sed"
Prompt% sed -i 's/\"Unix\"/\"Linux\"/g' t1
Prompt% sed -i 's/\"Unix sed\"/\"Linux SED\"/g' t1
Prompt% cat t1
This is "Linux"
This is "Linux SED"
Prompt%
0
SachinH