Como posso adicionar uma barra invertida antes de todos os espaços?

8

Como posso colocar uma barra invertida antes de cada espaço, de preferência usando os comandos trou sed?

Aqui está o meu script:

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

Supõe-se que ele substitua espaços por uma barra invertida seguida por um espaço, mas substitui apenas os espaços por uma barra invertida e não por uma barra invertida + espaço.

Esta é a saída que recebo:

hello\bye

Saída esperada:

hello\ bye
daka
fonte
Poderia, por favor, elaborar um pouco sobre isso? Você está procurando um script que altera um arquivo de texto? o que exatamente você está procurando?
Fabby
tr x ' ', onde xestá o personagem que você deseja substituir?
Maçaneta
atualizado - exemplo adicionado.
daka 14/03

Respostas:

17

trnão pode fazer vários caracteres. Use um destes:

  1. sed

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

    ou

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

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

    ou

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

    O Perl também tem uma função bacana chamada quotemetaque pode escapar de todas as coisas estranhas em uma string:

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

    O acima será impresso

    \@\!\#\$\%\^\&\*\(\)\ _\+\"\
    
  3. Você também pode usar printfe %q:

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

    Então, você poderia fazer

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

    Observe que isso, como o Perl, quotemetaescapará a todos os caracteres especiais, não apenas aos espaços.

    printf "%q\n" <<<$line
    
  4. Se você tem a linha em uma variável, basta fazê-lo diretamente no bash:

    echo ${line// /\\ }
    
Terdon
fonte
sim, isso funciona, mas não funciona quando se deseja substituir todas as ocorrências de "a" por uma folga + espaço.
daka 14/03
@sudoman Adicionei mais algumas opções, já que você já tem a linha em uma variável.
terdon
O printfbuilt-in do Bash tem funcionalidade semelhante a quotemeta- printf '%q\n' "$line"deve fazê-lo IIRC.
evilsoup
4

Não está AWKfaltando na lista de todas as soluções possíveis :)

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