Cómo escapar de una sola cita dentro de awk

111

Quiero hacer lo siguiente

awk 'BEGIN {FS=" ";} {printf "'%s' ", $1}'

Pero escapar de las comillas simples de esta manera no funciona

awk 'BEGIN {FS=" ";} {printf "\'%s\' ", $1}'

¿Como hacer esto? Gracias por la ayuda.

codeforester
fuente
Varios idiomas escapan a las comillas poniendo dos de ellos en una fila, tal vez intente eso.
Joshuahealy
Intenté awk 'BEGIN {FS = "";} {printf "' '% s' '", $ 1}', pero no se imprimió una sola comilla.
Esta página dice que es imposible incluir una comilla simple en una cadena entre comillas simples. Quizás tenga que convertir a comillas dobles.
Joshuahealy
2
Es imposible, pero dos cadenas de shell adyacentes entre comillas simples se pegan juntas en un parámetro. Y dos cadenas de shell entre comillas simples pegadas por caracteres que no son espacios en blanco también se pegan en un gran globo: 'abc'd'ef'es abcdef: literal más dmás literal. El destá fuera de las comillas, y se puede reemplazar ese dcon \'hacer 'abc'\''ef'que será evaluado abc'ef.
Kaz

Respuestas:

160

Quizás esto es lo que estás buscando:

awk 'BEGIN {FS=" ";} {printf "'\''%s'\'' ", $1}'

Es decir, con '\''usted cierra la apertura ', luego imprime un literal 'escapándose de él y finalmente abre de 'nuevo.

Steve
fuente
48
No tiene nada que ver con awk. El 'personaje cierra el 'literal de cadena de shell de apertura . El literal de shell no admite un escape de barra invertida para esto. La secuencia '\''hace el truco: cierra el literal de comillas simples, especifica el carácter de comillas (usando un escape que se admite fuera de los literales de comillas simples) y luego vuelve a abrir un nuevo literal de comillas simples. Puede pensar en ello como una secuencia de escape de cuatro caracteres para obtener una sola cita. :)
Kaz
2
@Steve: Muchas gracias por tu útil respuesta. ¡Me ahorraste muchos dolores de cabeza!
John Slegers
4
@syntaxerror Las citas que usa para preparar argumentos para invocar awkson simplemente una cuestión del intérprete de comandos que está usando para componer líneas de comando. El '{printf $2}'se convierte en algún argumento para una execvellamada al sistema o similar, donde simplemente se ve como una cadena C terminada en nulo sin comillas simples. Awk nunca ve las comillas y tampoco sed. Usted puede, de hecho, el uso de comillas dobles, pero comillas dobles no impedir la expansión de la concha de $2, por lo que tiene que escapar el signo de dólar con una barra invertida para que sea literal: "{printf \$2}".
Kaz
4
@syntaxerror Por costumbre, un script awk en línea generalmente se escapa con comillas simples, porque la sintaxis awk a menudo contiene elementos léxicos que son especiales para el shell, como literales de cadena entre comillas dobles y campos numerados indicados por signos de dólar. Si una expresión regular sed (o lo que sea) contiene sintaxis de shell, también debe tener cuidado. sed -e "s/$FOO/$BAR/"no funcionará si la intención es reemplazar el texto literal $FOOcon $BAR. La forma más sencilla sería sed -e 's/$FOO/$BAR/.
Kaz
1
@syntaxerror Si encierra programas awk entre comillas dobles, se encontrará con muchos escapes, como awk "{ print \"abc\", \$1 }". Cada vez que aparece una comilla doble en el programa awk, debe escaparse para que no cierre la cita de shell. Y compare esto: awk '{print "\\"}'(imprima una barra invertida) versus lo que se necesita con comillas dobles:, awk "BEGIN {print \"\\\\\" }"¡Uf! Ambas comillas tienen que escaparse y ambas barras invertidas. Los convertidos de concha \\ a \ lo que necesitamos \\\\ para codificar \\ .
Kaz
76

Una cita simple se representa mediante \x27

Como en

awk 'BEGIN {FS=" ";} {printf "\x27%s\x27 ", $1}'

Fuente

tiagojco
fuente
16
+1, pero es necesario agregar: \x27es una extensión; POSIX Awk solo reconoce \047. (también \47está bien si no va seguido de un dígito octal.)
hemflit
1
¿Cómo terminas \ x27 si tienes otro número después?
Jason Axelson
1
Jason, concatenas dos cadenas literales: "AAA \ x27" "1". O simplemente usa octal.
Hemflit
9
Utilice siempre octal ( \047), no hex ( \x27), códigos de escape; consulte awk.freeshell.org/PrintASingleQuote .
Ed Morton
35

Otra opción es pasar la comilla simple como una variable awk :

awk -v q=\' 'BEGIN {FS=" ";} {printf "%s%s%s ", q, $1, q}'

Ejemplo más simple con concatenación de cadenas:

# Prints 'test me', *including* the single quotes.
$ awk -v q=\' '{print q $0 q }' <<<'test me'
'test me'
mklement0
fuente
5
Esto es claro y conciso, especialmente si necesita usar muchas citas.
Peter Gluck
18
awk 'BEGIN {FS=" "} {printf "\047%s\047 ", $1}'
Sergio K
fuente
1
Siempre que recuerde que \047es la secuencia de escape octal para el carácter de comillas simples, creo que esta alternativa es la más legible.
Anthony Geoghegan
4

Para scripts pequeños, una forma opcional de hacerlo legible es usar una variable como esta:

awk -v fmt="'%s'\n" '{printf fmt, $1}'

Lo encontré conveniente en un caso en el que tuve que producir muchas veces el carácter de comillas simples en la salida y el \ 047 lo hacía totalmente ilegible

usuario1708042
fuente