Sathish
Sathish

Reputation: 1483

Sed to replace lower case string between two strings to upper case

i have a text file as below. I want to change the lower string between foo and var to upper case.

foo nsqlnqnsslkqn var
lnlnl.
foo DkqdQ HNOQii var

my expected output is

foo NSQLNQNSSLKQN var
lnllnl.
foo DKQDQ HNOQII var

i have used a one liner using sed sed 's/\(\foo\).*\(\var\)/\U\1\2/' testfile.txt but i get the following output

FOOVAR
lnlnl.
FOOVAR

Upvotes: 9

Views: 11161

Answers (1)

fedorqui
fedorqui

Reputation: 290445

You can use \U to make something become upper case:

$ sed 's/.*/\U&/' <<< "hello"
HELLO

And \E to stop the conversion:

$ sed -r 's/(..)(..)(.)/\U\1\E\2\U\3/' <<< "hello"
HEllO

In your case, just catch the blocks and place those \U and \E accordingly:

$ sed -r 's/(foo )(.*)( var)/\1\U\2\E\3/' file
foo NSQLNQNSSLKQN var
lnlnl.
foo DKQDQ HNOQII var
  • (foo )(.*)( var) catches three blocks: foo, the next text and var.
  • \1\U\2\E\3 prints them back, upcasing (is it a verb?) the second one (\U) and using the current case (\E) for the 3rd.

Without -r, to make it more similar to your current approach:

sed 's/\(foo \)\(.*\)\( var\)/\1\U\2\E\3/' file

So you can see that you were not catching the .* block, so you were printing back just foo and var.


From the manual of sed:

\L Turn the replacement to lowercase until a \U or \E is found,

\l Turn the next character to lowercase,

\U Turn the replacement to uppercase until a \L or \E is found,

\u Turn the next character to uppercase,

\E Stop case conversion started by \L or \U.

Upvotes: 23

Related Questions