web-dev-qa-db-fra.com

Comment échapper à une double citation entre guillemets?

Quelqu'un peut-il me montrer comment échapper à la citation double dans une double chaîne de bash?

Par exemple dans mon script shell

#!/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 parviens pas à obtenir correctement le message ENCLOSED BY \" avec des guillemets doubles. Je ne peux pas utiliser un guillemet simple pour ma variable parce que je veux utiliser la variable $dbtable.

243
Sean Nguyen

Utilisez une barre oblique inverse:

echo "\""     # Prints one " character.
259
Peter

Exemple simple de citations d'échappement dans Shell:

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

Cela se fait en finissant un déjà ouvert (_'_), en plaçant un échappé (_\'_), puis en en ouvrant un autre (_'_).

Alternativement:

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

Cela se fait en finissant un déjà ouvert (_'_), en insérant le devis dans un autre devis (_"'"_), puis en en ouvrant un autre (_'_).

Autres exemples: Échappement de guillemets simples dans des chaînes entre guillemets simples

65
kenorb

Je ne sais pas pourquoi cette vieille question est apparue aujourd’hui dans les listes étiquetées bash, mais juste au cas où de futurs chercheurs, gardez à l’esprit que vous pouvez éviter de vous échapper en utilisant des codes ASCII des caractères dont vous avez besoin pour faire écho. Exemple:

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

\x22 est le code ascii (en hex) 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 écho à la chaîne ci-dessus avec des barres obliques inverses, nous aurons besoin d’un écho désordonné sur deux lignes ... :)

Pour l'affectation de variable, 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 simples/doubles avec des outils sed ou 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.
47
George Vasiliou

Bash vous permet de placer des chaînes de manière adjacente, et elles finiront par être collées.

Donc ça:

$ echo "Hello"', world!'

produit

Hello, world!

L'astuce consiste à alterner entre les chaînes simples et les guillemets doubles selon les besoins. Malheureusement, cela devient rapidement très salissant. Par exemple:

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

produit

I like to use "double quotes" sometimes

Dans votre exemple, je le ferais à peu près comme ceci:

$ 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 la sortie suivante:

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 à l'aide de citations Unicode. Ce qui suit ne fonctionnera pas à bash - c'est juste pour 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 "‘ "ci-dessus seront interprétés par bash. Les guillemets comme " ' se retrouveront dans la variable résultante.

Si je donne le même traitement à l'exemple précédent, cela ressemble à ceci:

$ echoI like to use” ‘"double quotes" '“ sometimes

23
Beetle

vérifier printf ...

#!/bin/bash
mystr="say \"hi\""

Sans utiliser printf

echo -e $mystr

sortie: dire "salut"

Utiliser printf

echo -e $(printf '%q' $mystr)

sortie: dire\"salut \"

15
Danny Hong

Stockez le caractère de citation double en tant que variable:

 dqt = '"' 
 echo" guillemets doubles {{dqt} X $ {dqt} dans une chaîne entre guillemets "

Sortie:

 Les guillemets doubles "X" dans une chaîne entre guillemets 
14
12oclocker

Utilise $ "string".

Dans cet exemple, ce serait,

dbload = $ "charger les données locales \" 'gfpoint.csv'\"dans la table $ dbtable ZONES TERMINÉES PAR ',' CLÔTURÉES PAR '\"' LIGNES TERMINÉES PAR\"'\ n' \" IGNORE 1 LIGNES "

Remarque (à partir de la page de manuel ):

Une chaîne entre guillemets précédée d'un signe dollar ($ "chaîne") entraînera la traduction de la chaîne selon les paramètres régionaux en vigueur. Si les paramètres régionaux actuels sont C ou POSIX, le signe dollar est ignoré. Si la chaîne est traduite et remplacée, le remplacement est cité en double.

9
Trisha Chatterjee