bash - escape - ¿Cómo escapar de una comilla doble dentro de comillas dobles?
bash escape (8)
Almacena el carácter de comillas dobles como variable:
dqt=''"'' echo "Double quotes ${dqt}X${dqt} inside a double quoted string"
Salida:
Double quotes "X" inside a double quoted string
¿Alguien me puede mostrar cómo escapar de comillas dobles dentro de una cadena doble en bash?
Por ejemplo en mi 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"
No puedo obtener el CERRADO POR /"
con doble comillas de escape correctamente. No puedo usar comillas simples para mi variable porque quiero usar la variable $dbtable
.
Bash te permite colocar cadenas adyacentes, y simplemente terminarán pegadas.
Así que esto:
$ echo "Hello"'', world!''
produce
Hello, world!
El truco es alternar entre cadenas de comillas simples y dobles según sea necesario. Desafortunadamente, rápidamente se pone muy desordenado. Por ejemplo:
$ echo "I like to use" ''"double quotes"'' "sometimes"
produce
I like to use "double quotes" sometimes
En tu ejemplo, lo haría algo como esto:
$ 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
que produce el siguiente resultado:
load data local infile "''gfpoint.csv''" into table example FIELDS TERMINATED BY '','' ENCLOSED BY ''"'' LINES TERMINATED BY "''/n''" IGNORE 1 LINES
Es difícil ver qué está pasando aquí, pero puedo anotarlo usando citas de Unicode. Lo siguiente no funcionará en bash, es solo para ilustración:
dbload=
'' load data local infile "
''" ''gfpoint.csv''
"'' " into
'' '' table $dbtable FIELDS TERMINATED BY '','' ENCLOSED BY ''
'''' '' LINES
table $dbtable FIELDS TERMINATED BY '','' ENCLOSED BY ''
'''' '' LINES
table $dbtable FIELDS TERMINATED BY '','' ENCLOSED BY ''
'''' '' LINES
table $dbtable FIELDS TERMINATED BY '','' ENCLOSED BY ''
'''' '' LINES
table $dbtable FIELDS TERMINATED BY '','' ENCLOSED BY ''
'''' '' '' LINES
table $dbtable FIELDS TERMINATED BY '','' ENCLOSED BY ''
'' '' '' LINES
table $dbtable FIELDS TERMINATED BY '','' ENCLOSED BY ''
'' '' '' LINES
table $dbtable FIELDS TERMINATED BY '','' ENCLOSED BY ''
'' '' '' LINES
'''' '' ''/n''
”'' " IGNORE 1 LINES
''
Las citas como "''''” en lo anterior serán interpretadas por bash. Las citas como " ''
terminarán en la variable resultante.
Si le doy el mismo tratamiento al ejemplo anterior, se ve así:
$ echo
" I like to use
"
"double quotes"
"A
sometimes
"
Ejemplo simple de comillas de escape en shell:
$ echo ''abc''/'''abc''
abc''abc
$ echo "abc"/""abc"
abc"abc
Se hace al terminar ya abierto uno ( ''
), colocando uno escapado ( /'
), luego abriendo otro ( ''
).
Alternativamente:
$ echo ''abc''"''"''abc''
abc''abc
$ echo "abc"''"''"abc"
abc"abc
Se hace al terminar ya abierto uno ( ''
), colocando la cita en otra cita ( "''"
), y luego abriendo otro ( ''
).
Más ejemplos: Escape de comillas simples dentro de cadenas entre comillas simples
Hacer uso de $ "cadena".
En este ejemplo, sería,
dbload = $ "cargar datos locales /" ''gfpoint.csv'' / "en la tabla $ dbtable CAMPOS TERMINADOS POR '','' CERRADOS POR ''/"'' LÍNEAS TERMINADAS POR / "''/ n'' /" IGNORE 1 LINEAS "
Nota (de la página del manual ):
Una cadena entre comillas dobles precedida por un signo de dólar ($ "cadena") hará que la cadena se traduzca de acuerdo con la configuración regional actual. Si la configuración regional actual es C o POSIX, el signo de dólar se ignora. Si la cadena se traduce y se reemplaza, la sustitución se incluye entre comillas dobles.
No sé por qué este viejo problema apareció hoy en las listas etiquetadas de bash, pero por si acaso para futuros investigadores, tenga en cuenta que puede evitar escapar utilizando los códigos ASCII de los caracteres que necesita hacer eco. Ejemplo:
echo -e "this is /x22/x27/x22/x27/x22text/x22/x27/x22/x27/x22"
this is "''"''"text"''"''"
/x22
es el código ascii (en hexadecimal) para comillas dobles y /x27
para comillas simples. Del mismo modo puedes hacer eco de cualquier char.
Supongo que si tratamos de hacer eco de la cadena anterior con barras invertidas, necesitaremos un eco de dos filas desordenado ... :)
Para la asignación de variables este es el equivalente:
$ a=$''this is /x22text/x22''
$ echo "$a"
this is "text"
Si la variable ya está establecida por otro programa, aún puede aplicar comillas dobles / simples con herramientas sed o similares. Ejemplo:
$ 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.
Utilice una barra invertida:
echo "/"" # Prints one " character.
agregue "/"
antes de comillas dobles para escapar de él, en lugar de /
#! /bin/csh -f
set dbtable = balabala
set dbload = "load data local infile "/""''gfpoint.csv''"/"" into table $dbtable FIELDS TERMINATED BY '','' ENCLOSED BY ''"/""'' LINES TERMINATED BY "/""''/n''"/"" IGNORE 1 LINES"
echo $dbload
# load data local infile "''gfpoint.csv''" into table balabala FIELDS TERMINATED BY '','' ENCLOSED BY ''"'' LINES TERMINATED BY "''''" IGNORE 1 LINES
Echa un vistazo a printf ...
#!/bin/bash
mystr="say /"hi/""
Sin usar printf
echo -e $mystr
salida: di "hola"
Utilizando printf
echo -e $(printf ''%q'' $mystr)
salida: decir "hola"