Comando para escapar de una cadena en bash

99

Necesito un comando bash que convierta una cadena en algo que se escape. He aquí un ejemplo:

echo "hello\world" | escape | someprog

Cuando el comando de escape hace "hello\world"en "hello\\\world". Entonces, someprog puede usarlo "hello\\world"como espera. Por supuesto, este es un ejemplo simplificado de lo que realmente haré.

Usuario1
fuente
5
¿Cuál es la naturaleza del escape? En otras palabras, ¿qué personajes necesitan escapar? ¿Está buscando un escape de estilo C ++ (donde las pestañas se reemplazan por \ t, las nuevas líneas con \ n, las comillas con \ ", etc.)? Es difícil ayudar sin que el problema esté bien definido.
Michael Aaron Safyan
2
posible duplicado de echo que escapa a los argumentos de shell
P Shved
Esta pregunta podría significar cualquiera de una docena de cosas diferentes. En lugar de hacernos adivinar, sería útil que dijeras exactamente qué tipo de escape estás buscando.
Don Hatch
1
La pregunta era específica sobre el uso de \\ para \. Hay una respuesta aceptada.
Usuario1

Respuestas:

155

En Bash:

printf "%q" "hello\world" | someprog

por ejemplo:

printf "%q" "hello\world"
hello\\world

Esto también podría usarse a través de variables:

printf -v var "%q\n" "hello\world"
echo "$var"
hello\\world
Pausado hasta nuevo aviso.
fuente
6
Eso sí, %qestuvo roto durante más de una década hasta aproximadamente el 2012. Tuvo problemas con ~. También hay una sola línea sed portátil stackoverflow.com/a/20053121/1073695
Jo So
1
sed es de hecho mejor porque también puede escapar de los signos de dólar
untore
2
@untore: a='abc$def":'; printf '%q\n' "$a"da como resultado abc\$def\":(se escapa el signo de dólar). Este es Bash 4.3 (obtuve el mismo resultado en Bash 3.2). Qué versión estás usando?
Pausado hasta nuevo aviso.
3
para escapar del signo de dólar, use comillas simples en su lugar, por ejemplo: printf "%q" 'he$l&lo\world'
LeandroCR
bash's printf '%q\n' text cita el texto en bashformato (y para la configuración regional actual), por lo que solo funcionaría en el caso del OP si someprogtuvieran exactamente la misma sintaxis citas bashque es muy poco probable.
Stephane Chazelas
9

Pure Bash, utilice la sustitución de parámetros:

string="Hello\ world"
echo ${string//\\/\\\\} | someprog
Fritz G. Mehner
fuente
1
de esta manera, "hola mundo" no se escapa a "hola \ mundo": el enfoque de printf en la respuesta aceptada hace eso.
vchrizz
1
Además, "% q" no escapa a '/' como en "03/25/2017", que necesitaba escapar a "03 \ / 25 \ / 2017" (para que pudiera estar en un '/' regular delimitado expresión).
wrlee
0

Puede usar perl para reemplazar varios caracteres, por ejemplo:

$ echo "Hello\ world" | perl -pe 's/\\/\\\\/g'
Hello\\ world

Dependiendo de la naturaleza de su escape, puede encadenar múltiples llamadas para escapar de los personajes adecuados.

Michael Aaron Safyan
fuente
1
¿Por qué no sed? $ echo "hello \ world" | sed 's / \\ / \\\\ /'
Espacio
1
@Octopus, esa también es una opción válida. Resulta que me siento más cómodo con Perl, pero sí, eso también funciona.
Michael Aaron Safyan