1

The strings could be of form:

  1. com.company.$(PRODUCT_NAME:rfc1034identifier)
  2. $(PRODUCT_BUNDLE_IDENTIFIER)
  3. com.company.$(PRODUCT_NAME:rfc1034identifier).$(someRandomVariable)

I need help in writing regex that extract all the string inside $(..)

I created a regex like ([(])\w+([)]) but when I try to execute in shell script, it gives me error of unmatched parenthesis.

This is what I executed:

echo "com.io.$(sdfsdfdsf)"|grep -P '([(])\w+([)])' -o

I need to get all matching substrings.

3 Answers 3

2

Problem is use of double quotes in echo command which is interpreting $(...) as a command substitution.

You can use single quotes:

echo 'com.io.$(sdfsdfdsf)' | grep -oP '[(]\w+[)]'

Here is an alternative using builtin BASH regex:

$> re='[(][^)]+[)]'
$> [[ 'com.io.$(sdfsdfdsf)' =~ $re ]] && echo "${BASH_REMATCH[0]}"
(sdfsdfdsf)
Sign up to request clarification or add additional context in comments.

8 Comments

Error is gone, but this is nor producing any output. I would have expected sdfsdfdsf as output.
On my system this gives me (sdfsdfdsf) as output
I may be doing something wrong. I created a .sh file with your ideone code and when I run it, I get grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]] [-e pattern] [-f file] [--binary-files=value] [--color=when] [--context[=num]] [--directories=action] [--label] [--line-buffered] [--null] [pattern] [file ...]
@prabodhprakash: Does your grep support -P option? It is only supported by gnu grep.
Yep, @anubhava is probably using bash
|
2

You can do it quite simple with sed

echo 'com.io.$(asdfasdf)'|sed -e 's/.*(\(.*\))/\1/g'

Gives

asdfasdf

For two fields:

echo 'com.io.$(asdfasdf).$(ddddd)'|sed -e 's/.*((.*)).$((.*))/\1 \2/g'

Gives

asdfasdf ddddd

Explanation:

sed -e 's/.*(\(.*\))/\1/g'
          \_/\____/  \/
           |    |     |_ print the placeholder content
           |    |___ placeholder selecting the text inside the paratheses
           |____ select the text from beginning including the first paranthese    

7 Comments

You have added a \ before $ . I have to do without that \
use echo 'com.io.$(asdf)' single qoute will do it. I edited the answer.
The edited soln works, but for input like echo 'com.io.$(asdfasdf).$(hello world)'|sed -e 's/.*(\(.*\))/\1/g' - it prints only hello world. Can it be please modified to output all of them.
echo 'com.io.$(asdfasdf).$(ddddd)'|sed -e 's/.*((.*)).$((.*))/\1 \2/g' but you have to know how many fields you will get beforehand.
That is unknown. Essentially, I need to get all matching substrings.
|
1

Your question specifies "shell", but not "bash". So I'll start with a common shell-based tool (awk) rather than assuming you can use any particular set of non-POSIX built-ins.

$ cat inp.txt

com.company.$(PRODUCT_NAME:rfc1034identifier)
$(PRODUCT_BUNDLE_IDENTIFIER)
com.company.$(PRODUCT_NAME:rfc1034identifier).$(someRandomVariable)

$ awk -F'[()]' '{for(i=2;i<=NF;i+=2){print $i}}' inp.txt

PRODUCT_NAME:rfc1034identifier
PRODUCT_BUNDLE_IDENTIFIER
PRODUCT_NAME:rfc1034identifier
someRandomVariable

This awk one-liner defines a field separator that consists of opening or closing brackets. With such a field separator, every even-numbered field will be the content you're looking for, assuming all lines of input are correctly formatted and there are no parentheses embedded inside other parentheses.

If you did want to do this in POSIX shell alone, the following would be an option:

#!/bin/sh

while read line; do
  while expr "$line" : '.*(' >/dev/null; do
    line="${line#*(}"
    echo "${line%%)*}"
  done
done < inp.txt

This steps through each line of input, slicing it up using the parentheses and printing each slice. Note that this uses expr, which most likely an external binary, but is at least included in POSIX.1.

4 Comments

Can we do it w/o input from file? I have a string that I get.
This worked for me, echo 'com.company.$(PRODUCT_NAME:rfc1034identifier).$(someRandomVariable)' | awk -F'[()]' '{for(i=2;i<=NF;i+=2){print $i}}'
1 more question - if I have to evaluate the expression $i - how would I do it?
I'm gonna say .. "probably". :-) What do you mean by "the expression $i"? In awk, $i means "the field identified by the variable i".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.