I want to replace words between parentheses in unix/Linux- as an example below. I am trying to automate this so that it makes my work easy with just one code included.

I have the below string in my ksh script

   echo "Export file to below names (ABC, DEF, GHI)"

I would like to be as below

   echo "Export file to below names ('ABC', 'DEF', 'GHI')"
  • 1
    With Vim: :%s/(\zs.*\ze)/\=substitute(submatch(0), '\w\+', "'&'", 'g')/ – Satō Katsura Aug 25 '16 at 13:54
  • I have tried using sed command which is mentioned below by Ipor. But it didn't worked as it put quotations after each words. sed -e "s/($1)/'\1'/g" – nehal Aug 25 '16 at 14:13
$ echo "Export file to below names (ABC, DEF, GHI)" | sed -e "s/\([A-Z][A-Z][A-Z]\)/'\1'/g"
Export file to below names ('ABC', 'DEF', 'GHI')
  • Thanks Ipor. What if I have condition like this ------ WHERE Name in (NEW,OLD,CLOSED) Can we use the same command to change it to ('NEW','OLD','CLOSED') ? – nehal Aug 25 '16 at 14:15
  • sed -e "s/\([A-Z]*\)\([,)]\)/'\1'\2/g" or sed -e "s/\([A-Z][A-Z]\+\)/'\1'/g – Ipor Sircer Aug 25 '16 at 14:26

In Perl, almost in a readable way:

echo "Export file to below names (ABC, DEF, GHI)" |  
  perl -lne '@a = /(.*\()(.*)(\).*)/; $a[1] =~ s/\w+/\x27$&\x27/g; print @a'

The first match splits the line in three parts and captures all: anything up to a left parenthesis ((.*\()), anything ((.*)), and a right parenthesis plus anything ((\).*)). We drop them into array @a, and run a substitution on the second element (counting from zero). The substitution s/\w+/\x27$&\x27/g matches strings of "word characters" (\w+) and replaces with the matching part (from $&) surrounded by single quotes. The quotes are escaped in hex to avoid an annoying quote-dance with the shell.

Of course with Perl you could do unreadable stuff too, like a sed-style substitution within another substitution:

echo "Export file to below names (ABC, DEF, GHI)" |
  perl -pe 's,\(.*\), $_ = $&; s/\w+/\x27$&\x27/g; $_ ,e; ' 
Export file to below names ('ABC', 'DEF', 'GHI')

Here, the final e makes the outer substitution interpret the replacement as a snippet of Perl code, which takes the matching part from $&, and edits it as above. I used $_ as a temporary variable here since $& is read-only. The replacement snipped could be moved to a function, which would perhaps make the line more readable.

  • Is there any way we can replace a string like below, just need to replace character strings only- Where Name in (old, new, closed) and value in (1,2,3) to Where Name in ('old', 'new', 'closed') and value in (1,2,3) – nehal Aug 25 '16 at 20:15
  • @nehal, yeah, of course. Instead of the \w I used, you can give a list of characters in brackets to match any of them, like [xyz], or even a range [a-zA-Z]. Look here for more, there's a bunch of examples. That's specifically for Perl regular expressions, sed and others differ annoyingly in various little places, so some study may be required when changing tools. – ilkkachu Aug 25 '16 at 21:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.