1

I'm using cut function for getting all sub strings. For example: I have a string named "v1.2.3". I want assign 1 to major. 2 to minor and 3 to bug (remove first character is always v)

For example below:

  major=$(echo $tag | cut -d'.' -f1)
  minor=$(echo $tag | cut -d'.' -f2)
  bug=$(echo $tag | cut -d'.' -f3)
  echo "$major $minor $bug"

This script expands on 3 lines. My question is: how can I return all f1 f2 and f3 in one call and assign back to major minor and bug at same time.

I also try to use regular expression. for example: v1.2.3 will be split to 1,2 and 3 respectively but it seems not work.

  re="^v(.*).(.*).(.*)$"
  [[ $tag =~ $re ]] && major="${BASH_REMATCH[1]}" && minor="${BASH_REMATCH[2]}" && patch="${BASH_REMATCH[3]}"
  echo $major
  echo $minor
  echo $patch

thanks.

Trần Kim Dự
  • 5,872
  • 12
  • 55
  • 107
  • @tripleee thanks. I have updated my question for using regular expression. Please take a look. – Trần Kim Dự Oct 19 '16 at 04:29
  • Your regex is nondeterministic. If you want to split on literal dots, `IFS='.'` as suggested in the suggested duplicate. (FWIW the regular expression to match a literal dot is `\.` or equivalently `[.]`.) To trim a leading prefix, `${tag#v}` produces the value of `tag` with any leading `v` removed. – tripleee Oct 19 '16 at 04:31
  • @tripleee thanks. but using this method. I will lost some information about $2 $3 that I need in other place. How can I fix this – Trần Kim Dự Oct 19 '16 at 04:37
  • @TrầnKimDự: Check out my answer below. – Inian Oct 19 '16 at 05:09
  • Please flag as duplicate and post your answers to the nominated duplicate instead if the method you want to propose is not already documented there. – tripleee Oct 19 '16 at 05:21
  • @tripleee: my bad! didn't wanted to exactly duplicate it, as it involved a minor substitution to be done. Will share the documentation link right-away. – Inian Oct 19 '16 at 05:27

2 Answers2

3

This can be done in pure bash string-manipulation See shell-parameter-expansion for various techniques.

$ IFS="." read -r major minor bug <<< "v1.2.3" # read the strings to variables
$ major="${major/v/}"                          # removing the character 'v' from major
$ printf "%s %s %s\n" "$major" "$minor" "$bug" # printing the individual variables
1 2 3
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Inian
  • 80,270
  • 14
  • 142
  • 161
2

I've recently learned of "read". Goes a little like this:

#set field separator to match your delimiter
ifsOld=$IFS
IFS='.'

read major minor bug <<<$(echo $tag | cut -d'.' -f 1,2,3)

IFS=$ifsOld

eg:

$ IFS='.'
$ read major minor bug <<<$(echo 127.1.2.123 | cut -d'.' -f 1,2,3)
$ echo $major $minor $bug
127 1 2
$
GrahamA
  • 59
  • 6