2

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.

3
  • What is your expected output? Commented Mar 31, 2022 at 20:21
  • Regarding I would like to return a single value - which value and based on what criteria? Commented Apr 1, 2022 at 2:30
  • @HaiVu expected output: "I want to be able to retrieve a version number (n.n.n) from a file (yaml)" Commented Apr 2, 2022 at 15:14

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you, this didn't work for version: 1.0.0+1 as it returned 1.0.01. Apologies I didn't realise i had missed the : in the last version in the sample section.
0

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 text
  • version: - 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).

Comments

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.