2010-09-30 28 views
147

¿Alguien puede mostrarme cómo escapar de comillas dobles dentro de una cadena doble en bash?¿Cómo escapar de una comilla doble dentro de comillas dobles?

Por ejemplo en mi script de 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" 

no puedo conseguir el CERRADOS POR \" con el escape doble cita correctamente. No puedo usar comillas simples para mi variable porque quiero usar la variable $dbtable.

+45

, debe familiarizarse con el concepto de [Inyección SQL] (http: // en. wikipedia.org/wiki/SQL_injection) antes de comenzar a escribir código como este. – Daenyth

+1

También vea http://mywiki.wooledge.org/BashFAQ/050 –

+0

posible duplicado de [Escapar comillas simples dentro de cadenas entre comillas simples] (http://stackoverflow.com/questions/1250079/escaping-single-quotes- within-single-quote-strings) – kenorb

Respuesta

170

Utilice una barra invertida:

echo "\""  # Prints one " character. 
+3

No funciona. 'x = ls; if [-f "$ (que" \ "" $ x "\" ")"]; entonces el eco existe; más echo roto; fi; 'da roto mientras que' ... [-f "$ (which $ x)"]; ... 'o' ... [-f $ (que "$ x")]; ... 'funciona bien. Los problemas surgirían cuando '$ x' o el resultado de' $ (que "$ x") 'da cualquier cosa con un espacio u otro carácter especial. Una solución alternativa es usar una variable para contener el resultado de 'which', pero ¿bash es realmente incapaz de escapar de una cita o estoy haciendo algo mal? – Luc

+0

Estoy tratando de usar el siguiente 'grep -oh" \ "\" "$ counter" \ "" \ w * "' como parte de una sintaxis de bash en la que '$ counter' es una variable. no le gusta ningún pensamiento –

10

la salida printf ...

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

Sin usar printf salida

echo -e $mystr 

: decir "hola"

Usando printf

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

de salida: decir \ "hola \"

+1

Tenga en cuenta que 'printf' también escapa más caracteres, como' '',' ('y') ' –

+0

' printf% q' genera cadenas listas para 'eval', no formateadas para 'echo -e'. –

+2

No hay ninguna razón para ajustar el 'printf' con un [uso inútil de' echo'] (http://www.iki.fi/era/unix/award.html#echo). Tus dos ejemplos han roto las citas. La solución correcta es hacer una cita doble de la variable. – tripleee

35

ejemplo simple de escapar de las citas con cáscara:

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

Está hecho de acabado ya abierta una ('), colocando escapado uno (\'), luego abriendo otro (').

Alternativamente:

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

Está hecho de acabado ya abierto uno ('), colocando cita en otra cita ("'"), entonces la apertura de otro (').

Más ejemplos: Escaping single-quotes within single-quoted strings

+1

Probé sh -c "echo '{" key ":" value "}'" e incluso sh -c "echo '{' '"' 'clave' '"' ':' '"' 'value' '" ''} '"en un esfuerzo por adjuntar las palabras clave y valor entre comillas dobles, pero en ambos casos obtuve {key: value} –

17

Bash le permite colocar cuerdas adyacentes, y que sólo va a terminar siendo pegadas entre sí.

Así que esto:

$ echo "Hello"', world!' 

produce

Hello, world! 

El truco es alternar entre las cadenas individuales y entre comillas dobles si es necesario. Desafortunadamente, rápidamente se vuelve muy complicado.Por ejemplo:

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

produce

I like to use "double quotes" sometimes 

En su 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 lo que está pasando aquí, pero puede anotar que el uso de citas Unicode. El siguiente no funcionará en bash - es sólo para la ilustración:

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

Las citas como "''" en lo anterior serán interpretadas por bash. Las cotizaciones como " ' terminarán en la variable resultante.

Si doy el mismo tratamiento al ejemplo anterior, se ve así:

$ echoI like to use"double quotes"sometimes

3

Hacer uso de $ "cadena".

En este ejemplo, sería,

dbload = $ "datos de carga infile locales \" 'gfpoint.csv' \" en la tabla $ CAMPOS DBTABLE terminados en '' CERRADO POR '\" "LÍNEAS TERMINATED pOR \ " '\ n' \" IGNORE 1 LÍNEAS"

Nota (del man page):

una cadena entre comillas dobles precedida por un signo de dólar ($ "cadena") hará que la cuerda se traduzca de acuerdo a la configuración regional actual. Si la configuración regional actual es C o POSIX, se ignora el signo de dólar. Si la cadena se traduce y reemplaza, el reemplazo se cotiza a doble.

-4

añadir "\" antes de comillas dobles para escapar de ella, 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 
+2

Voto a favor: ¿por qué estás publicando una respuesta' csh' a una pregunta 'bash'? Los dos son completamente distintos e incompatibles. – tripleee

20

No sé por qué este viejo problema apareció hoy en la fiesta de etiquetado listados, pero por si acaso para futuros investigadores Tenga en cuenta que puede evitar escaparse utilizando los códigos ASCII de los caracteres que necesita para 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 hex) para comillas dobles y \x27 para comillas simples. Del mismo modo, puedes repetir cualquier char.

supongo que si tratamos de repetir la secuencia anterior con barras invertidas, necesitaremos un desordenado dos filas de barra invertida eco ... :)

Para la asignación variable de esto es el equivalente:

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

Si la variable ya está configurada 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. 
+0

+1 porque resolvió el problema de agregar una variable PS1 a ~/.profile 'echo 'export PS1 =' \ [\ 033 [00; 31m \] $ {? ## 0} $ ([$? -ne 0] && echo \ x22 \ x22) \ [\ 033 [00; 32m \] \ u \ [\ 033 [00m \] @ \ [\ 033 [00; 36m \] \ h \ [\ 033 [00m \] [\ [\ 033 [01; 33m \] \ d \ t \ [\ 033 [00m \]] \ [\ 033 [01; 34m \] \ w \ n \ [\ 033 [00m \] $ ([$ {EUID} -ne 0] && echo \ x22 $ \ x22 || echo \ x22 # \ x22) '' >> ~/.profile' –

+2

esto probablemente debería marcarse como la respuesta. – qodeninja

3

tienda el carácter de comillas dobles como variables:

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

Salida:

 
Double quotes "X" inside a double quoted string 
Cuestiones relacionadas