409 votes

Comment échapper à un guillemet double à l'intérieur de guillemets doubles ?

Comment échapper aux guillemets doubles à l'intérieur d'une chaîne double en Bash ?

Par exemple, dans mon shell script

#!/bin/bash

dbload="load data local infile \"'gfpoint.csv'\" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY \"'\n'\" IGNORE 1 LINES"

Je ne peux pas obtenir le ENCLOSED BY '\"' avec des guillemets doubles pour s'échapper correctement. Je ne peux pas utiliser de guillemets simples pour ma variable, car je veux utiliser la variable $dbtable .

1 votes

0 votes

5 votes

@kenorb Ça ne ressemble pas à une duplication de cette question...

381voto

Peter Points 38320

Utilisez une barre oblique inversée :

echo "\""     # Prints one " character.

17 votes

Ne fonctionne pas. x=ls; if [ -f "$(which "\""$x"\"")" ]; then echo exists; else echo broken; fi; donne cassé alors que ... [ -f "$(which $x)" ]; ... ou ... [ -f $(which "$x") ]; ... fonctionnent très bien. Les problèmes surviennent lorsque $x ou le résultat de $(which "$x") donne tout ce qui comporte un espace ou un autre caractère spécial. Une solution de contournement consiste à utiliser une variable pour contenir le résultat de la commande which Mais est-ce que bash est vraiment incapable d'échapper à une citation ou est-ce que je fais quelque chose de mal ?

0 votes

J'essaie d'utiliser ce qui suit grep -oh "\"\""$counter"\""\w*" dans le cadre d'une syntaxe bash où en $counter est une variable. Il n'aime pas les pensées.

145voto

kenorb Points 2464

Un exemple simple d'échappement des guillemets dans le shell :

$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc

Pour ce faire, il faut terminer un dossier déjà ouvert ( ' ), en plaçant celui qui est échappé ( \' ), puis d'en ouvrir un autre ( ' ).

Alternativement :

$ echo 'abc'"'"'abc'
abc'abc
$ echo "abc"'"'"abc"
abc"abc

Il s'agit de terminer un dossier déjà ouvert ( ' ), placer une citation dans une autre citation ( "'" ), puis d'en ouvrir un autre ( ' ).

Plus d'exemples : Échapper aux guillemets simples dans les chaînes de caractères à guillemets simples

91voto

George Vasiliou Points 4142

Je ne sais pas pourquoi ce vieux problème est apparu aujourd'hui dans les listes de balises Bash, mais juste au cas où pour les futurs chercheurs, gardez à l'esprit que vous pouvez éviter l'échappement en utilisant les codes ASCII des caractères que vous devez répercuter.

Exemple :

 echo -e "This is \x22\x27\x22\x27\x22text\x22\x27\x22\x27\x22"
 This is "'"'"text"'"'"

\x22 est le code ASCII (en hexadécimal) pour les guillemets doubles, et \x27 pour les guillemets simples. De même, vous pouvez faire écho à n'importe quel caractère.

Je suppose que si nous essayons de faire l'écho de la chaîne ci-dessus avec des backslashes, nous aurons besoin d'un écho désordonné à deux rangées de backslashes... :)

Pour l'affectation de variables, c'est l'équivalent :

 $ a=$'This is \x22text\x22'
 $ echo "$a"
 This is "text"

Si la variable est déjà définie par un autre programme, vous pouvez toujours appliquer des guillemets doubles/simples avec sed ou des outils similaires.

Exemple :

 $ b="Just another text here"
 $ echo "$b"
 Just another text here
 $ sed 's/text/"'\0'"/' <<<"$b" #\0 is a special sed operator
 Just another "0" here #this is not what i wanted to be
 $ sed 's/text/\x22\x27\0\x27\x22/' <<<"$b"
 Just another "'text'" here #now we are talking. You would normally need a dozen of backslashes to achieve the same result in the normal way.

37voto

Beetle 952580 Points 706

Bash vous permet de placer des cordes de manière adjacente, et elles finiront juste par être collées les unes aux autres.

Alors ça :

$ echo "Hello"', world!'

produit

Hello, world!

L'astuce consiste à alterner entre les chaînes de caractères à guillemets simples et doubles selon les besoins. Malheureusement, cela devient vite très désordonné. Par exemple :

$ echo "I like to use" '"double quotes"' "sometimes"

produit

I like to use "double quotes" sometimes

Dans votre exemple, je ferais quelque chose comme ça :

$ dbtable=example
$ dbload='load data local infile "'"'gfpoint.csv'"'" into '"table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"'"'"' LINES "'TERMINATED BY "'"'\n'"'" IGNORE 1 LINES'
$ echo $dbload

qui produit le résultat suivant :

load data local infile "'gfpoint.csv'" into table example FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY "'\n'" IGNORE 1 LINES

Il est difficile de voir ce qui se passe ici, mais je peux l'annoter en utilisant des guillemets Unicode. Ce qui suit ne fonctionnera pas dans bash - c'est juste une illustration :

dbload= ' load data local infile " '" 'gfpoint.csv' "' " into '" table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY ' "' " '" ' LINES "' TERMINATED BY " '" '\n' "' " IGNORE 1 LINES '

Les guillemets comme " ' ' " dans le texte ci-dessus seront interprétés par bash. Les guillemets comme " ' se retrouvera dans la variable résultante.

Si j'applique le même traitement à l'exemple précédent, on obtient le résultat suivant :

$ echo " I like to use " ' "double quotes" ' " sometimes "

34voto

12oclocker Points 66

Stocke le caractère guillemet double dans une variable :

dqt='"'
echo "Double quotes ${dqt}X${dqt} inside a double quoted string"

Sortie :

Double quotes "X" inside a double quoted string

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X