sed special character replace not working in shell script
Solution 1
I don't think you are capturing the group right. Try this?
sed 's:\([]\[\^\$\.\*\/]\):\\\1:g'
Edit: nevermind, I wasn't aware of the relevance of &. The problem is you need to extra escape the slashes in replacement because of the parsing and passing to sub shell.
sed 's:[]\[\^\$\.\*\/]:\\\\&:g'
Also, if you used $(command) instead of backticks, you don't need the extra \'s
Solution 2
So the task is to write a sed
substitution that escapes all special characters (defined as the characters []^$.*/
, and I added \
too) in a string.
The substitution might look like
s/[][\^$.*/]/\\&/g
Note that we don't really have to escape any of the characters in the [...]
set (the \
is treated literally too, so we can't escape anything in there), and that the only thing we have to make sure of is that ]
is in the very beginning of it.
So the script (rewritten as a shell function, and revamped in other ways) becomes
function escape
{
printf '%s\n' "$1" | sed 's/[][\^$.*/]/\\&/g'
}
Testing:
$ escape 'hello world'
hello world
$ escape '*.*'
\*\.\*
$ escape '\/'
\\\/
$ escape '/\'
\/\\
$ escape 's/[][\^$.*/]/\\&/g'
s\/\[\]\[\\\^\$\.\*\/\]\/\\\\&\/g
Related videos on Youtube
drapkin11
Updated on September 18, 2022Comments
-
drapkin11 over 1 year
I want to write a script 'test.sh' that will take a user's input and replace all special characters with a '\' + the character. My script:
#!/bin/bash echo 'input='"$1" arg=`echo "$1" | sed 's:[]\[\^\$\.\*\/]:\\&:g'` echo 'modified input='"$arg"
My command works on the string 'xy', which does not have any special characters. I run this in my terminal:
test.sh xy
And I obtain:
input=xy modified input=xy
However, when I run this:
test.sh x.y
I get:
input=x.y modified input=x&y
I don't understand why this script is not working. I expect to get:
input=x.y modified input=x\.y
I think the problem lies in this sed command but I'm not sure where:
sed 's:[]\[\^\$\.\*\/]:\\&:g'
-
drapkin11 over 11 yearsYes, if I add two more '\' as you did will work. But I don't see why they are needed. Is there a reference you can point me to understand this? Also, not sure what you mean regarding $(command)
-
Drake Clarris over 11 yearsenclosing commands in backticks uses simple substitution - so the the command is parsed by the current shell.
$(command)
opens a subshell, so anything inside the parens runs as if on its own command line. See for more info: wiki.bash-hackers.org/syntax/expansion/cmdsubst