Quote:
Originally Posted by czezz
(Post 6137212)
This is an example input file:
Code:
cat test.input
9fcfdec4-58a9-4612-b80a-741669bd485d\nfa17fd04-80e1-44c1-bd5e-418bdd332100\nfa17fd04-80e1-44c1-bd5e-418bdd332100
When I use following "sed" on it, it works as expected (each \n is replaced by .)
Code:
# cat test.input | sed -r 's/[\\n]+/./g'
9fcfdec4-58a9-4612-b80a-741669bd485d.fa17fd04-80e1-44c1-bd5e-418bdd332100.fa17fd04-80e1-44c1-bd5e-418bdd332100
BUT, if I try to execute it as script, it fails... what am I doing wrong???
Code:
cat script.sh
-------------
#!/bin/bash
X=`cat test.input | sed -r 's/[\n]+/./g'`
echo $X
# ./script.sh
9fcfdec4-58a9-4612-b80a-741669bd485d\nfa17fd04-80e1-44c1-bd5e-418bdd332100\nfa17fd04-80e1-44c1-bd5e-418bdd332100
|
From the Bash manpage (emphasis by me):
Code:
Command Substitution
Command substitution allows the output of a command to replace the com‐
mand name. There are two forms:
$(command)
or
`command`
...
When the old-style backquote form of substitution is used, backslash
retains its literal meaning except when followed by $, `, or \. The
first backquote not preceded by a backslash terminates the command sub‐
stitution. When using the $(command) form, all characters between the
parentheses make up the command; none are treated specially.
The command substition instructions
$() and
`` do not behave the same. Two backslashes
\\ inside
`` are replaced by
Bash with a single backslash
\. So the
sed command
Code:
echo `sed -r 's/[\\n]+/./g' test.input`
that is executed inside
`` (I assume you tested the command substitution with
\\ as well) is:
Code:
sed -r 's/[\n]+/./g' test.input
If you only use a single backslash
\ (as you did inside your script)
Code:
echo `sed -r 's/[\n]+/./g' test.input`
then it is not treated specially by
Bash inside
`` because it is not followed by either
$,
`, or
\. So the
sed command that is executed executed inside
`` is same as before:
Code:
sed -r 's/[\n]+/./g' test.input
The character sequence
\n, however, is interpreted as a newline by
sed and NOT two literal, independent characters
\ and
n, as is the case in your input. Since there is no actual
newline in your input
sed will not replace the literal character sequence
\ and
n.
The backslash is not treated specially by
Bash when it is used inside
$(), i.e.,
Bash passes it to
sed as is. So you have two possible choices to achieve your goal:
Code:
echo `sed -r 's/[\\\n]+/./g' test.input` # three backslash
or
Code:
echo $(sed -r 's/[\\n]+/./g' test.input) # two backslash
In both cases
sed will see a double backslash
\\ and interpret it as one literal backslash followed by an
n; as is the case in your input.