Jacky Lee
Jacky Lee

Reputation: 1233

sed to replace "_", "&", "$" with "\_", "\&", "\$" respectively

In writing latex, usually there is a bibliography file, which sometimes contains _, &, or $. For example, the journal name "Nature Structural & Molecular Biology", the article title "Estimating The Cost Of New Drug Development: Is It Really $802 Million?", and the volume number "suppl_2".

So I need to convert these symbols into \_, \&, and \$ respectively, i.e. adding a backslash in front, so that latex compiler can correctly identify them. I want to use sed to do the conversion. So I tried

sed 's/_/\_/' <bib.txt >new.txt

but the generated new.txt is exactly the same as bib.txt. I thought _ and \ needed to be escaped, so I tried

sed 's/\_/\\\_/' <bib.txt >new.txt

but no hope either. Can somebody help? Thanks.

Upvotes: 9

Views: 26049

Answers (4)

user237419
user237419

Reputation: 9064

sed 's/\([_&$]\)/\\\1/g'

e.g.

eu-we1:~/tmp# cat zzz
bla__h&thisis&not the $$end
eu-we1:~/tmp# sed 's/\([_&$]\)/\\\1/g' < zzz
bla\_\_h\&thisis\&not the \$\$end
eu-we1:~/tmp# 

Upvotes: 3

Michael J. Barber
Michael J. Barber

Reputation: 25052

You're running into some difficulties due to how the shell handles strings. The backslash needs to be doubled:

sed 's/_/\\_/g'

Note that I've also added a 'g' to indicate that the replacement should applied globally on the lines, not just to the first match.

To handle all three symbols, use a character class:

sed 's/[_&$]/\\&/g'

(The ampersand in the replacement text is a special character referring to the matched text, not a literal ampersand character.)

Upvotes: 13

Dogbert
Dogbert

Reputation: 222428

You need to escape it twice.

➜  8080667  sed 's/_/\\_/' new.txt
In writing latex, usually there is a bibliography file, which sometimes contains \_, &, or $. For example, the journal name "Nature Structural & Molecular Biology", the article title "Estimating The Cost Of New Drug Development: Is It Really $802 Million?", and the volume number "suppl_2".
➜  8080667  

Upvotes: 1

tdenniston
tdenniston

Reputation: 3519

You need to escape your \. Like this: sed 's/_/\\_/' new.txt.

Edit: Also, to modify new.txt in place, you need to pass sed the -i flag:

sed -iBAK 's/_/\\_/' new.txt

Upvotes: 1

Related Questions