HRaz
HRaz

Reputation: 35

sed match dollar and single quote characters

I have the following string in my file:

"sequence A$_{0}$B$_{}$C$_{'0}$"

I want to move any single quotes that appear after a $_{ to go before it, i.e.

"sequence A$_{0}$B$_{}$C'$_{0}$"

This is my sed command (using # as a delimiter) for just the part with the quote:

$ echo "$_{'0}$" | sed "s#$_{'#'\$_{#g"
'$_{0}$

So this works. However my text contains strings that shouldn't be matched, e.g.

$ echo "$_{0}$" | sed "s#$_{'#'\$_{#g"
/home/ppatest/texlive/2010/texmf{0}$`  

I understand that $_ gives the last argument of previous command. I checked:

$ echo $_
/home/ppatest/texlive/2010/texmf

But I don't understand why $_{' matches "$_{0}$"

Furthermore, I found that to prevent the Unix shell from interpreting the dollar sign as a shell variable, the script should be put in single quotes. But I can't do that as I am also matching on single quotes.

Upvotes: 1

Views: 1001

Answers (2)

NeronLeVelu
NeronLeVelu

Reputation: 10039

echo "\$_{'0}\$" | sed "s#\(\$_{\)'#'\1#g"
  • escape the $ when using double quote
  • use group avoiding several confusing \$ when possible
  • use double quote when simple quote are part of the pattern

Upvotes: 0

fedorqui
fedorqui

Reputation: 289815

Your current approach uses double quotes in sed to be able to handle the single quotes. However, as you can see, this produces the expansion of $, so that you can end up having broader problems.

What I recommend is to use a sed expression with single quotes. To match and replace single quotes, you need to close the leading ', the enclose the ' within " and then open the expression again:

$ echo "he'llo" | sed 's#'"'"'#X#'
heXllo

In your case:

sed 's#$_{'"'"'#'"'"'$_{#g' file

This way, you keep using single quotes and prevent the expansion of $.

Test

$ cat a
hello $_{'0}$ bye
$_{'0}$
yeah
$ sed 's#$_{'"'"'#'"'"'$_{#g' a
hello '$_{0}$ bye
'$_{0}$
yeah

Upvotes: 2

Related Questions