Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

regex

bash

sed

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
like image 934
Sathish Avatar asked Mar 28 '14 16:03

Sathish


People also ask

How do you substitute a string with sed?

Find and replace text within a file using sed command Use Stream EDitor (sed) as follows: sed -i 's/old-text/new-text/g' input.txt. The s is the substitute command of sed for find and replace. It tells sed to find all occurrences of 'old-text' and replace with 'new-text' in a file named input.txt.

What does sed E mean?

The -e tells sed to execute the next command line argument as sed program. Since sed programs often contain regular expressions, they will often contain characters that your shell interprets, so you should get used to put all sed programs in single quotes so your shell won't interpret the sed program.

Which function is used to changing case in strings?

The toLowerCase() method converts the string specified into a new one that consists of only lowercase letters and returns that value. It means that the old, original string is not changed or affected in any way.


1 Answers

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.

like image 98
fedorqui 'SO stop harming' Avatar answered Sep 27 '22 19:09

fedorqui 'SO stop harming'