¿Cómo escapar de los caracteres especiales en una cadena?

Suponiendo que $file contiene un valor de un nombre de archivo, digamos Dr" A.tif. En la programación bash, ¿cómo podría escapar de las comillas simples y cualquier otro carácter especial de $file sin eliminar el carácter especial?

Actualización del 9 de julio de 2014

Como solicitud de @Gilles , siguiente fragmento de código que no «puede manejar Dr" A.tif:

files=$(find /path/ -maxdepth 1 -name "*.[Pp][Dd][Ff]" -o -name "*.[Tt][Ii][Ff]") echo "${files}" > ${TEMP_FILE} while read file do newfile=$(echo "${file}" | sed "s, ,\\ ,g") ## line 1 done < ${TEMP_FILE} 

Después de haber probado el respuesta de @Patrick en line 1, parece funcionar para mí. Pero si tengo un archivo como Dr\^s A.tif, printf no parece ayudar, me muestra Dr\^s\ A.tif. Si lo intento manualmente en la consola de esta manera:

printf "%q" "Dr\^s A.tif"

Tendré este resultado:

Dr\\\^s\ A.tif

¿Alguna idea de cómo manejar esto?

Comentarios

  • en qué contexto ¿espera usar $ file? ¿O es este problema asignando la cadena con el carácter especial a $ file?
  • En realidad, el comando de búsqueda me devuelve una matriz de lista de archivos. Y luego recorro esta lista de archivos en $ file variable.
  • Usted ' ha recibido algunas respuestas correctas aquí, pero probablemente no sean las respuestas a la pregunta que realmente estás ' preguntando. De su comentario aquí, sospecho fuertemente que está ' en el camino equivocado. No podemos ' ayudarte mucho porque sigues sin mostrar tu código. Sin embargo, le recomiendo que lea ¿Por qué mi script de shell se ahoga con espacios en blanco u otros caracteres especiales? como fondo. Muestre su guión y explique lo que quiere hacer.

Responda

Usted puede usar el printf incorporado con %q para lograr esto. Por ejemplo:

$ file="Dr" A.tif" $ printf "%q\n" "$file" Dr\"\ A.tif $ file=" foo$bar\baz`" $ printf "%q\n" "$file" \ foo\$bar\\baz\` 

De la documentación de bash en printf:

In addition to the standard format specifications described in printf(1) and printf(3), printf interprets: %b expand backslash escape sequences in the corresponding argument %q quote the argument in a way that can be reused as shell input %(fmt)T output the date-time string resulting from using FMT as a format string for strftime(3) 

Comentarios

  • Este no ' no funciona con ciertos casos. cuando necesite conservar las comillas dobles.
  • @ user3467349 funciona bien con las comillas. Estoy ' apuesto a que ' estás intentando algo como printf '%s' "foo". Primero debe comprender cómo funciona el análisis de argumentos en el shell. Consulte gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 antes del # 6.
  • ¿Podría proporcione un ejemplo de esta cadena impresa con printf y sin otras manipulaciones It doesn't have a: ""
  • Su problema no tiene nada que ver con printf. Su problema es que no ' no quiere que el shell analice su cadena. Para hacer eso, debe pasar su entrada al shell de una manera en la que no ' ni siquiera intente analizarla. Una forma de hacerlo sería read -r -p 'input: ' && printf '%q\n' "$REPLY" y proporcionar la entrada cuando se le solicite.
  • Como he ' he dicho varias veces ahora. No saber cómo pasar datos sin procesar al shell no es ' t un problema con printf. Quizás debería hacer una pregunta en lugar de criticar una solución que no tiene nada que ver con su problema.

Responder

Pruebe: –

file=Dr\"\ A.tif echo $file Dr" A.tif 

o

file="Dr" A.tif" echo $file Dr" A.tif 

o si la cadena contiene un doble quote: –

file="Dr" A.tif" echo $file Dr" A.tif 

Hay buenos tutoriales sobre cómo escapar y citar en la red. Comience con este .

Responda

No «No es necesario escapar los nombres de archivo que está manejando en un script. El escape solo es necesario si desea poner un nombre de archivo como literal en un script, o para pasar varios nombres de archivo como un solo flujo de entrada a otra secuencia de comandos.

Dado que «está recorriendo la salida de find, este es una de las formas más sencillas (!) de manejar todas las rutas posibles :

while IFS= read -r -d "" do file_namex="$(basename -- "$REPLY"; echo x)" file_name="${file_namex%$"\nx"}" do_something -- "$file_name" done <(find "$some_path" -exec printf "%s\0" {} +) 

Responder

rápido y (muy) sucio

find . | sed "s/^/"/" | sed "s/$/"/" 

Responder

Muchas de estas respuestas, incluida la más votada con printf "%q" no funciona en todos los casos sin manipulación adicional.Sugeriría lo siguiente (ejemplo a continuación):

cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn"t contain lexemes: "" EOF

Comentarios

  • Disculpe la pregunta n00b, pero ¿puede explicar cómo usaría esto para escapar caracteres en una cadena? Si copio el código que escribes en mi terminal, simplemente imprime 2015-11-07T03: 34: 41Z aplicación [postgres.0000]: [TAG] consulta de búsqueda de texto no ' t contienen lexemas: " " … nada se escapa.
  • Eso ' s literalmente el punto, todos los caracteres especiales son interpretados como caracteres literales, no por su significado especial. Intente repetir " la cadena anterior " para ver la diferencia.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *