4

I am learning bash and trying to understand the different ways of making a substitution and assigning it to a variable.

Specifically, I'm changing Unix slashes ('/') to Windows ('\').

References:

With thanks to Seth and terdon.


Updated version. Original at bottom.

#!/bin/bash
origPath="/home/django_auth_lifecycle/urls.py"

path=$origPath
path=${path//\//\\}                      #Works
echo "Via bash (2-slash, no-g): $path"

path=$origPath
path=${path//\//\\}                      #Works
echo "Via bash (no dollar): $path"

path=$origPath
echo "${path}" | sed -e 's/\//\\/g'     #Works, but don't know how to assign to var
#echo "Via sed (slash, quotes): $path"

path=$origPath
path=$(echo "$path" | sed s/'\/'/'\\'/g)   #Works
echo "Via sed (slash, quotes): $path"

path=$origPath
path=$(echo $path | sed s:'\/':'\\':g)   #Works
echo "Via sed (colon, quotes): $path"

path=$origPath                           #This and all following are
path=sed 's:/:\\:g' <<<$path             #s:/:\\:g: No such file or directory
echo "Via sed/<<< (colon): $path"

path=$origPath
path=sed 's/\//\\:g' <<<$path
echo "Via sed/<<< (slash): $path"

path=$origPath
path=sed 's/"\/"/"\\":g' <<<$path
echo "Via sed/<<< (slash, quotes): $path"

Output:

$ bash ./initial_script3.sh
Via bash (2-slash, no-g): \home\django_auth_lifecycle\urls.py
Via bash (no dollar): \home\django_auth_lifecycle\urls.py
./initial_script3.sh: line 13: ${echo "${path}" | sed -e 's/\//\\/g'}: bad substitution
Via sed (slash, quotes): /home/django_auth_lifecycle/urls.py
Via sed (slash, quotes): \home\django_auth_lifecycle\urls.py
Via sed (colon, quotes): \home\django_auth_lifecycle\urls.py
./initial_script3.sh: line 25: s:/:\\:g: No such file or directory
Via sed/<<< (colon): /home/django_auth_lifecycle/urls.py
./initial_script3.sh: line 29: s/\//\\:g: No such file or directory
Via sed/<<< (slash): /home/django_auth_lifecycle/urls.py
./initial_script3.sh: line 33: s/"\/"/"\\":g: No such file or directory
Via sed/<<< (slash, quotes): /home/django_auth_lifecycle/urls.py

Output with debugging:

$ bash -x ./initial_script3.sh
+ origPath=/home/django_auth_lifecycle/urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ path='\home\django_auth_lifecycle\urls.py'
+ echo 'Via bash (2-slash, no-g): \home\django_auth_lifecycle\urls.py'
Via bash (2-slash, no-g): \home\django_auth_lifecycle\urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ path='\home\django_auth_lifecycle\urls.py'
+ echo 'Via bash (no dollar): \home\django_auth_lifecycle\urls.py'
Via bash (no dollar): \home\django_auth_lifecycle\urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ sed -e 's/\//\\/g'
+ echo /home/django_auth_lifecycle/urls.py
\home\django_auth_lifecycle\urls.py
+ path=/home/django_auth_lifecycle/urls.py
++ sed 's/\//\\/g'
++ echo /home/django_auth_lifecycle/urls.py
+ path='\home\django_auth_lifecycle\urls.py'
+ echo 'Via sed (slash, quotes): \home\django_auth_lifecycle\urls.py'
Via sed (slash, quotes): \home\django_auth_lifecycle\urls.py
+ path=/home/django_auth_lifecycle/urls.py
++ sed 's:\/:\\:g'
++ echo /home/django_auth_lifecycle/urls.py
+ path='\home\django_auth_lifecycle\urls.py'
+ echo 'Via sed (colon, quotes): \home\django_auth_lifecycle\urls.py'
Via sed (colon, quotes): \home\django_auth_lifecycle\urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ path=sed
+ 's:/:\\:g'
./initial_script3.sh: line 25: s:/:\\:g: No such file or directory
+ echo 'Via sed/<<< (colon): /home/django_auth_lifecycle/urls.py'
Via sed/<<< (colon): /home/django_auth_lifecycle/urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ path=sed
+ 's/\//\\:g'
./initial_script3.sh: line 29: s/\//\\:g: No such file or directory
+ echo 'Via sed/<<< (slash): /home/django_auth_lifecycle/urls.py'
Via sed/<<< (slash): /home/django_auth_lifecycle/urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ path=sed
+ 's/"\/"/"\\":g'
./initial_script3.sh: line 33: s/"\/"/"\\":g: No such file or directory
+ echo 'Via sed/<<< (slash, quotes): /home/django_auth_lifecycle/urls.py'
Via sed/<<< (slash, quotes): /home/django_auth_lifecycle/urls.py

Original

Below is what I've tried. Unfortunately, I can only get one method to work (sed with a pipe and quoting each element). The first one was working, I swear, and now it's not.

What am I doing wrong?


#!/bin/bash
origPath="/home/django_auth_lifecycle/urls.py"

path=$origPath
path=${$path/\//\\/g}                    #WAS working, now not
echo "Via bash: $path"                   # ${$path/\//\\/g}: bad substitution

path=$origPath
path=${path/\//\\/g}                     #Bad output:
echo "Via bash (no dollar): $path"       #'\/ghome/django_auth_lifecycle/urls.py'

path=$origPath
path=$(echo $path | sed s/'\/'/'\\'/g)   #Works
echo "Via sed (slash, quotes): $path"

path=$origPath
#path=$(echo $path | sed s/\//\\/g)      #No error, but output=input
echo "Via sed (slash): $path"

path=$origPath
path=$(echo $path | sed s:'\/':'\\':g)   #Works
echo "Via sed (colon, quotes): $path"

path=$origPath
path=$(echo $path | sed s:\/:\\:g)       #sed: -e expression #1, char 7:
echo "Via sed (colon): $path"            #     unterminated `s' command

path=$origPath                           #This and all following are
path=sed 's:/:\\:g' <<<$path             #s:/:\\:g: No such file or directory
echo "Via sed/<<< (colon): $path"

path=$origPath
path=sed 's/\//\\:g' <<<$path
echo "Via sed/<<< (slash): $path"

path=$origPath
path=sed 's/"\/"/"\\":g' <<<$path
echo "Via sed/<<< (slash, quotes): $path"

Output:

$ bash ./initial_script3.sh
./initial_script3.sh: line 5: ${$path/\//\\/g}: bad substitution
Via bash: /home/django_auth_lifecycle/urls.py
Direct echo: \/ghome/django_auth_lifecycle/urls.py
Via bash (no dollar): \/ghome/django_auth_lifecycle/urls.py
./initial_script3.sh: line 14: \/ghome/django_auth_lifecycle/urls.py: No such file or directory
Via echo bash (no dollar): /home/django_auth_lifecycle/urls.py
Via sed (slash, quotes): \home\django_auth_lifecycle\urls.py
Via sed (slash): /home/django_auth_lifecycle/urls.py
Via sed (colon, quotes): \home\django_auth_lifecycle\urls.py
sed: -e expression #1, char 7: unterminated `s' command
Via sed (colon):
./initial_script3.sh: line 34: s:/:\\:g: No such file or directory
Via sed/<<< (colon): /home/django_auth_lifecycle/urls.py
./initial_script3.sh: line 38: s/\//\\:g: No such file or directory
Via sed/<<< (slash): /home/django_auth_lifecycle/urls.py
./initial_script3.sh: line 42: s/"\/"/"\\":g: No such file or directory
Via sed/<<< (slash, quotes): /home/django_auth_lifecycle/urls.py

Output with debugging:

$ bash -x ./initial_script3.sh
+ origPath=/home/django_auth_lifecycle/urls.py
+ path=/home/django_auth_lifecycle/urls.py
./initial_script3.sh: line 5: ${$path/\//\\/g}: bad substitution
+ echo 'Via bash: /home/django_auth_lifecycle/urls.py'
Via bash: /home/django_auth_lifecycle/urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ echo 'Direct echo: \/ghome/django_auth_lifecycle/urls.py'
Direct echo: \/ghome/django_auth_lifecycle/urls.py
+ path='\/ghome/django_auth_lifecycle/urls.py'
+ echo 'Via bash (no dollar): \/ghome/django_auth_lifecycle/urls.py'
Via bash (no dollar): \/ghome/django_auth_lifecycle/urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ path=echo
+ '\/ghome/django_auth_lifecycle/urls.py'
./initial_script3.sh: line 14: \/ghome/django_auth_lifecycle/urls.py: No such file or directory
+ echo 'Via echo bash (no dollar): /home/django_auth_lifecycle/urls.py'
Via echo bash (no dollar): /home/django_auth_lifecycle/urls.py
+ path=/home/django_auth_lifecycle/urls.py
++ sed 's/\//\\/g'
++ echo /home/django_auth_lifecycle/urls.py
+ path='\home\django_auth_lifecycle\urls.py'
+ echo 'Via sed (slash, quotes): \home\django_auth_lifecycle\urls.py'
Via sed (slash, quotes): \home\django_auth_lifecycle\urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ echo 'Via sed (slash): /home/django_auth_lifecycle/urls.py'
Via sed (slash): /home/django_auth_lifecycle/urls.py
+ path=/home/django_auth_lifecycle/urls.py
++ sed 's:\/:\\:g'
++ echo /home/django_auth_lifecycle/urls.py
+ path='\home\django_auth_lifecycle\urls.py'
+ echo 'Via sed (colon, quotes): \home\django_auth_lifecycle\urls.py'
Via sed (colon, quotes): \home\django_auth_lifecycle\urls.py
+ path=/home/django_auth_lifecycle/urls.py
++ sed 's:/:\:g'
sed: -e expression #1, char 7: unterminated `s' command
++ echo /home/django_auth_lifecycle/urls.py
+ path=
+ echo 'Via sed (colon): '
Via sed (colon):
+ path=/home/django_auth_lifecycle/urls.py
+ path=sed
+ 's:/:\\:g'
./initial_script3.sh: line 34: s:/:\\:g: No such file or directory
+ echo 'Via sed/<<< (colon): /home/django_auth_lifecycle/urls.py'
Via sed/<<< (colon): /home/django_auth_lifecycle/urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ path=sed
+ 's/\//\\:g'
./initial_script3.sh: line 38: s/\//\\:g: No such file or directory
+ echo 'Via sed/<<< (slash): /home/django_auth_lifecycle/urls.py'
Via sed/<<< (slash): /home/django_auth_lifecycle/urls.py
+ path=/home/django_auth_lifecycle/urls.py
+ path=sed
+ 's/"\/"/"\\":g'
./initial_script3.sh: line 42: s/"\/"/"\\":g: No such file or directory
+ echo 'Via sed/<<< (slash, quotes): /home/django_auth_lifecycle/urls.py'
Via sed/<<< (slash, quotes): /home/django_auth_lifecycle/urls.py
7
  • 2
    echo ${origPath//\//\\}
    – Cyrus
    Jan 9, 2015 at 20:40
  • @Cyrus Updated my script with that near the top. It gives incorrect output. :( Jan 9, 2015 at 21:03
  • 3
    @aliteralmind, note carefully there are 2 leading / and no trailing /g: echo "${origPath//\//\\}". // to replace all, \/ to search for a slash (escaped to not clash with ->), / to separate the search and replace test, \\ to substitute a backslash. See gnu.org/software/bash/manual/… Jan 9, 2015 at 21:30
  • //\//\\ != /\//\\/g
    – Cyrus
    Jan 9, 2015 at 21:30
  • With sed: echo "${origPath}" | sed -e 's/\//\\/g'
    – Cyrus
    Jan 9, 2015 at 21:36

1 Answer 1

7

With "Parameter Expansion":

origPath="/home/django_auth_lifecycle/urls.py"
path="${origPath//\//\\}"
echo $path

Output:

\home\django_auth_lifecycle\urls.py


With a pipe, sed and "Command Substitution":

origPath="/home/django_auth_lifecycle/urls.py"
path="$(echo "${origPath}" | sed -e 's/\//\\/g')"
echo $path

Output:

\home\django_auth_lifecycle\urls.py


With sed, "Here String" and "Command Substitution":

origPath="/home/django_auth_lifecycle/urls.py"
path="$(sed -e 's/\//\\/g' <<< "${origPath}")"
echo $path

Output:

\home\django_auth_lifecycle\urls.py
3
  • Excellent. Thank you. Learned a lot today. One more question: Can you show how to use alternative delimiters with the parameter expansion version? (Like path="${origPath::\/:\\}". Jan 9, 2015 at 23:17
  • This is not possible. Parameter expansion has no alternative delimiters for search and replace like sed. If you use two : then you can make "Substring Expansion" like this: a="highway"; echo "${a:4:5}". Output: way
    – Cyrus
    Jan 9, 2015 at 23:28
  • I wrote about this on my blog: aliteralmind.wordpress.com/2015/01/10/bashcrash Jan 10, 2015 at 6:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .