I want to be able to retrieve a version number (n.n.n) from a file (yaml) that follows a string.
sdk: ">=0.2.4 <3.1.1"
version: ^2.3.1
sdk: flutter
version: 1.0.0 1
sed -n '/version:/p sample.yaml
which returns the line for the string provided "version:", I then piped this into another command grep to pattern match the line for the version number:
sed -n '/version:/p sample.yaml | grep -oP '(\[0-9\] ).(\[0-9\] ).(\[0-9\] )'
I would like to see if there is a more efficient way to do this, and if string = 'sdk' from the example the returned value returns both when I would like to return a single value.
CodePudding user response:
Use awk
awk '/version:/ {
pos=match($2, /[0-9] \.[0-9] \.[0-9] /);
print substr($2, pos, RLENGTH); }' sample.yaml
match() returns the position in the field where the regexp is found, and sets RLENGTH to its length.
CodePudding user response:
You can use
sed -nE 's/.*version:[^0-9]*([0-9][0-9.]*).*/\1/p' file
grep -oP 'version:\D*\K\d[\d.]*' file
See an online demo:
#!/bin/bash
s='sdk: ">=0.2.4 <3.1.1"
version: ^2.3.1
sdk: flutter
version 1.0.0 1'
sed -nE 's/.*version:[^0-9]*([0-9][0-9.]*).*/\1/p' <<< "$s"
# => 2.3.1
grep -oP 'version:\D*\K\d[\d.]*' <<< "$s"
# => 2.3.1
The version:\D*\K\d[\d.]* grep regex matches version: substring, then any zero or more non-digits (with \D*), then omits the matched text (with \K) and then matches and returns a digit and then any zero or more digits or dots (with \d[\d.]*).
The sed POSIX ERE (see -E option enabling this regex flavor) pattern matches
.*- any textversion:- a fixed substring[^0-9]*- zero or more non-digits([0-9][0-9.]*)- Group 1 (\1): a digit and then zero or more digits or dots.*- any text.
The whole match is replaced with Group 1 value, the p flag prints the result of the successful substitution (-n suppresses default line output).
