¿Cómo puedo agregar una barra diagonal inversa antes de todos los espacios?

8

¿Cómo puedo poner una barra diagonal inversa antes de cada espacio, preferiblemente usando tro sedcomandos?

Aquí está mi guión:

#!/bin/bash
line="hello bye"
echo $line | tr ' ' "\\\ "

Se supone que esto reemplaza los espacios con una barra invertida seguida de un espacio, pero solo reemplaza los espacios con una barra invertida y no una barra invertida + espacio.

Este es el resultado que obtengo:

hello\bye

Rendimiento esperado:

hello\ bye
daka
fuente
¿Podría por favor explicar un poco sobre eso? ¿Estás buscando un script que cambie un archivo de texto? ¿Que es exactamente lo que está buscando?
Fabby
tr x ' ', ¿dónde xestá el personaje que quieres reemplazar?
Pomo de la puerta
actualizado - ejemplo agregado.
daka

Respuestas:

17

trNo puedo hacer varios personajes. Utilice uno de estos en su lugar:

  1. sed

    echo "$line" | sed 's/ /\\ /g' 
    

    o

    sed 's/ /\\ /g' <<< "$line"
    
  2. Perl

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

    o

    perl -pe 's/ /\\ /g'<<< "$line"
    

    Perl también tiene una función ingeniosa llamada quotemetaque puede escapar de todas las cosas extrañas en una cadena:

    line='@!#$%^&*() _+"'
    perl -ne 'print quotemeta($_)' <<< $line
    

    Lo anterior se imprimirá

    \@\!\#\$\%\^\&\*\(\)\ _\+\"\
    
  3. También puedes usar printfy %q:

    %q  quote the argument in a way that can be reused as shell input
    

    Entonces, podrías hacer

    echo "$line" | printf "%q\n" 
    

    Tenga en cuenta que esto, como el de Perl, quotemetaescapará a todos los caracteres especiales, no solo a los espacios.

    printf "%q\n" <<<$line
    
  4. Si tiene la línea en una variable, puede hacerlo directamente en bash:

    echo ${line// /\\ }
    
terdon
fuente
sí, esto funciona, pero no funciona cuando se desea reemplazar todas las ocurrencias de "a" con una reacción + espacio.
daka
@sudoman Agregué algunas opciones más ya que ya tienes la línea en una variable.
terdon
La función printfincorporada de Bash tiene una funcionalidad similar a quotemeta- printf '%q\n' "$line"debería hacerlo IIRC.
evilsoup
4

Hay AWKque faltan en la lista de todas las posibles soluciones :)

$ echo "Hello World" | awk '{gsub(/ /,"\\ ");print}'                                                                             
Hello\ World
Sergiy Kolodyazhnyy
fuente