1

I think I am too stupid for this. In every programming language I tried it works flawlessly, but not with sed on the shell. Could someone explain to me why

echo "Version: 4.4.0.157.165" | sed -E 's/.*\Version: (\d+\.\d+.\d+\.\d+)\.\d+//'

Prints the whole string again instead of 4.4.0.157.

best regards

It works on regex101: https://regex101.com/r/eZ1gT7/2035

LucidEx
  • 31
  • 5
  • 2
    Why is t here ``\`` before `V`? `\d` is not supported, use `[0-9]` instead. – Wiktor Stribiżew Aug 20 '19 at 07:32
  • I read something about matching the whole line first, but you are right it doesn't make sense. `echo "Version: 4.4.0.157.165" | sed -E 's/Version: ([0-9]+\.[0-9]+.[0-9]+\.[0-9]+)\.[0-9]+//'` now prints nothing though. `echo "Version: 4.4.0.157.165" | sed -E 's/([0-9]+\.[0-9]+.[0-9]+\.[0-9]+)\.[0-9]+//' ` prints Version, but even if the reverse of what I want to achieve is true, why doesn't it print .165 as well? – LucidEx Aug 20 '19 at 07:38
  • It prints nothing because you removed everything. You must revert captured substrings with `\1`, `\2`, etc placeholders in the replacement part and you have it empty. Read my answer. – Wiktor Stribiżew Aug 20 '19 at 07:44

1 Answers1

1

You need to use

echo "Version: 4.4.0.157.165" | sed -E 's/.*Version: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+/\1/'

Or, a bit more enhanced:

sed -E 's/.*Version: ([0-9]+(\.[0-9]+){3})\.[0-9]+/\1/' <<< "Version: 4.4.0.157.165"

See the online sed demo

Notes:

  • Do not use backslashes where they are not supposed to be (remove \ before V)
  • \d is not supported in sed, use [0-9] instead, even with -E option
  • You need to use a \1 placeholder in the replacement part to put back what you captured in Group 1
  • One of the dots was not escaped
  • If your consecutive subpatterns repeat, it is a good idea to use the range quantifier. [0-9]+(\.[0-9]+){3} matches 1+ digits, and then 3 occurrences of . and 1+ digits.

On second thought, you might want to extract the version from a larger string. Then, use

sed -nE 's/.*Version: ([0-9]+(\.[0-9]+){3})\.[0-9].*/\1/p' <<< "Version: 4.4.0.157.165"
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • 1
    Thank you very much for the explanation. I didn't know the online sed demo exist as well. I will use it for further testing. The \1 placeholder explains a lot in hindsight. – LucidEx Aug 20 '19 at 07:49
  • @LucidEx Also, if you test your regex at regex101.com, make sure you understand the constructs used to be able to convert to the POSIX regex standard. Also, not all features that can be used in a PCRE regex can be used in `sed` [POSIX regex](https://www.regular-expressions.info/posix.html). – Wiktor Stribiżew Aug 20 '19 at 07:51