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).