Willi Fischer
Willi Fischer

Reputation: 455

Capitalize string between quotes with sed

Background: I am moving some sql statements from SQL server to Oracle. While Oracle is case sensitive in string comparison, SQL server is not, by default I think. In my case all strings have to be in upper case.

in the original I might have something like

xyz like '%foo%' and ...

which I want to convert to

xyz like '%FOO%' and ...

i.e. anything between quotes following 'like ' has to be capitalised.


here is what I have tried and does not work:

echo "like 'aaa' aaa"|sed 's/like\( '.*'\)/like\U\1/g'

for some reason this gives me

like 'AAA' AAA

I don't understand why it matches the whole line, even after the second quote.

This does also not work:

echo "like 'aaa' aaa"|sed 's/like\( '[^']*\)/like\U\1/g'

why? I don't understand the error message sed: -e expression #1, char 26: unterminated 's' command

Any ideas? Thanks a lot!

Upvotes: 0

Views: 94

Answers (2)

Sundeep
Sundeep

Reputation: 23667

When using 's/SEARCH/REPLACE/' with outer single quotes, you cannot use single quotes inside it as well... but there is a workaround with using \x27 instead

$ echo "like 'aaa' aaa"|sed 's/like\( \x27.*\x27\)/like\U\1/g'
like 'AAA' aaa


These two are equivalent, 's/like\( '.*'\)/like\U\1/g' is simply three strings concatenated 's/like( ' and .* and '\)/like\U\1/g'

$ echo "like 'aaa' aaa" | sed 's/like\( '.*'\)/like\U\1/g'
like 'AAA' AAA
$ echo "like 'aaa' aaa" | sed 's/like\( .*\)/like\U\1/g'
like 'AAA' AAA

$ # a different example
$ echo "like 'aaa' aaa" | sed 's/like/'LIKE'/g'
LIKE 'aaa' aaa


Also, .* will try to match as much as possible, so use this instead:

$ echo "xyz like '%foo%' and 'bar' ..." | sed 's/\(like[^\x27]*\x27\)\([^\x27]*\)/\1\U\2/g'
xyz like '%FOO%' and 'bar' ...

vs

$ echo "xyz like '%foo%' and 'bar' ..." | sed 's/like\( \x27.*\x27\)/like\U\1/g'
xyz like '%FOO%' AND 'BAR' ...
  • like[^\x27]*\x27 matches like followed by non-single quote character and a single quote character
  • [^\x27]* then we match as many non-single quote characters as possible which will then be subjected to \U in replacement section

Upvotes: 3

codeforester
codeforester

Reputation: 42999

You can use double quotes to protect the single quotes, like so:

echo "like 'aaa' aaa" | sed "s/like\( '[^']*'\)/like\U\1/g"

Outputs:

like 'AAA' aaa

Upvotes: 1

Related Questions