Replace to first matching character using sed

You're almost there! Instead of looking for "0 or more characters" inside the \text{} block as you do with \\text{\(.*\)}, look for "0 or more non-} characters":

$ sed 's/\^\\text{\([^}]*\)}/\^{\\{text{\1}}/g' foo.tex 
something $^{\{text{TT}}$ and more stuff
something $^{\{text{T}}$ and more stuff
something $^{\{text{M\times N}}$ and more stuff
something $^{\{text{T}} {otherstuff}$

The g I added to the end turns on global matching which means that all matches on the line will be replaced. Note that this assumes that matches are non-overlapping, it won't work for something like this:

something $^{\{text{$^{\{text{BB}}$}}$ and more stuff

I am assuming that isn't a problem here though.


One method to overcome the greedy regular expression problem is to explicitly look for a string of non-delimiter characters, followed by the delimiter character. At the same time, you can probably simplify your replacement syntax via:

sed 's/\^\(\\text{[^}]*}\)/\^{\1}/' input.tex 

It should be possible to use

sed 's/\^\(\\text{[^}]*}\)/\^{\1}/g' input.tex 

for multiple matches per line.


I propose this:

$ sed 's/\$\^\\\([^}]*\)/$^\{\\\1}/' file
something $^{\text{TT}}$ and more stuff
something $^{\text{T}}$ and more stuff
something $^{\text{M\times N}}$ and more stuff
something $^{\text{T}} {otherstuff}$