Assume a text string my_string

$ my_string="foo bar=1ab baz=222;"

I would like to extract the alphanumeric string between keyword baz and the semi-colon.

How do I have to modify the following grep code using regex assertions to also exclude the trailing semi-colon?

$ echo $my_string | grep -oP '(?<='baz=').*'
  • What should be the outcome for foo baz=x; bar=y;? (x or x; bar=y?). And for baz=x; baz=y;? – Stéphane Chazelas Jun 29 '17 at 14:30

Unless the string that you want to extract may itself contain ;, the simplest thing is probably to replace . (which matches any single character) with [^;] (which matches any character excluding ;)

$ printf '%s\n' "$my_string" | grep -oP '(?<='baz=')[^;]*'

With grep linked to libpcre 7.2 or newer, you can also simplify the lookbehind using the \K form:

$ printf '%s\n' "$my_string" | grep -oP 'baz=\K[^;]*'

Those will print all occurrences in the string and assume the matching text doesn't contain newline characters (since grep processes each line of input separately).


Steeldriver's answer is accurate, but I have a hard time with lookaheads/behinds and would do it like this for readability (with bash):

my_string="foo bar=1ab baz=222;"
[[ $my_string =~ $regex ]] &&
  echo "${BASH_REMATCH[1]}"

Also easy with sed:

sed -n 's/.*baz=\([^;]*\).*/\1/p' <<< $my_string

With any POSIX shell:

  • For the text between the first occurrence of baz= and the last occurrence of ; after that:

    my_string="foo bar=1ab baz=222;"
    case $my_string in
      (*) result=
  • for the text between the first occurrence of baz= and the next occurrence of ; after that, replace % with %% above

  • for the last occurrence of baz=, replace # with ##.

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.