9

How can I put a backslash before every space, preferably by using tr or sed commands?

Here is my script:

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

This is supposed to replace spaces with a backslash followed by a space, but it's only replacing the spaces with a backslash and not backlash+space.

This is the output I get:

hello\bye

Expected output:

hello\ bye
Zanna
  • 69,223
  • 56
  • 216
  • 327
olfek
  • 1,245
  • 5
  • 13
  • 21

2 Answers2

20

tr can't do multiple characters. Use one of these instead:

  1. sed

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

    or

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

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

    or

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

    Perl also has a nifty function called quotemeta which can escape all odd things in a string:

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

    The above will print

    \@\!\#\$\%\^\&\*\(\)\ _\+\"\
    
  3. You can also use printf and %q:

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

    So, you could do

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

    Note that this, like Perl's quotemeta will escape all special characters, not just spaces.

    printf "%q\n" <<<$line
    
  4. If you have the line in a variable, you could just do it directly in bash:

    echo ${line// /\\ }
    
terdon
  • 98,183
  • 15
  • 197
  • 293
  • yes this works, but does not work when wanting to replace all occurences of "a" with a backlash+space. – olfek Mar 14 '15 at 19:22
  • @sudoman I added some more options since you have the line in a variable already. – terdon Mar 14 '15 at 20:04
  • Bash's [`printf` builtin](http://wiki.bash-hackers.org/commands/builtin/printf) has functionality similar to `quotemeta` -- `printf '%q\n' "$line"` should do it IIRC. – evilsoup Mar 15 '15 at 19:19
5

There is AWK missing in the list of all the possible solutions :)

$ echo "Hello World" | awk '{gsub(/ /,"\\ ");print}'                                                                             
Hello\ World
Sergiy Kolodyazhnyy
  • 103,293
  • 19
  • 273
  • 492