Reputation: 331
I want to replace some strings with other strings in a folder containing .ly files (.ly files are files used to write music, which can then be converted to svg files). One problem is that the files contain backslashes (\).
Anyway, what I want to do is to replace the following strings:
\f with \fffff
\p with \ppppp
mordent with reverseturn
r4 with \mordent
Each string I want to replace (and each string it is replaced for) has a space in the end. This is because I don't want strings like
\pt to be replaced with \pppppt
Similarly, because backslashes matter, strings like
\ff should stay the same (only f with a slash before and a space after should be replaced).
The code that I am using to achieve this is:
for f in *.ly
do
filename="${f}"
sed -i -- "s@\p @\ppppp @g; s@\f @\fffff @g; s@mordent @reverseturn @g; s@r4 @\maxima @g" $filename;
done
I am using delimited @ instead of backslash exactly to achieve this.
However, the program is giving some totally weird behavior. In particular:
\f stays the same (wrong behavior, the right behavior is to get transformed to \fffff)
\p is converted to \ppppp (correct behavior)
\stemUp is converted to \stemUppppp (wrong behavior, the right behavior is to remain as it was)
This is perplexing me and giving me a headache. In particular, why it works correctly for \p but not for \f considering that it is the exact same code.
For reference, I attached a file before and after applying the sed commands.
Thanks in advance for any help!
NB: I am using Ubuntu 16.04 and sed (GNU 4.2.2).
Upvotes: 1
Views: 347
Reputation: 23677
$ echo '12p3 p \p foo' | sed 's/\p /\ppppp /g'
12p3 ppppp \ppppp foo
$ echo '12p3 p \p foo' | sed 's/\\p /\\ppppp /g'
12p3 p \ppppp foo
\
is a meta-character, to match it literally, it needs to be escaped, i.e \\
\
is special within double quotes too(because of bash, nothing to do with sed) - so don't use double quotes unless needed(for ex: sed substitution with bash variables). See also Difference between single and double quotes in BashUpvotes: 3