bash 从 shell 脚本中的文件中提取版本号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6245293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:36:42  来源:igfitidea点击:

Extract version number from file in shell script

bashshellscriptingsed

提问by Dougnukem

I'm trying to write a bash script that increments the version number which is given in

我正在尝试编写一个 bash 脚本来增加在

{major}.{minor}.{revision}

For example.

例如。

1.2.13

Is there a good way to easily extract those 3 numbers using something like sed or awk such that I could increment the {revision} number and output the full version number string.

有没有一种好方法可以使用 sed 或 awk 之类的东西轻松提取这 3 个数字,以便我可以增加 {revision} 数字并输出完整的版本号字符串。

回答by jlliagre

$ v=1.2.13
$ echo "${v%.*}.$((${v##*.}+1))"
1.2.14


$ v=11.1.2.3.0
$ echo "${v%.*}.$((${v##*.}+1))"
11.1.2.3.1


Here is how it works:

下面是它的工作原理:

The string is split in two parts.

字符串分为两部分。

  • the first one contains everything but the last dot and next characters: ${v%.*}
  • the second one contains everything but all characters up to the last dot: ${v##*.}
  • 第一个包含除最后一个点和下一个字符之外的所有内容: ${v%.*}
  • 第二个包含除最后一个点之前的所有字符之外的所有内容: ${v##*.}

The first part is printed as is, followed by a plain dot and the last part incremented using shell arithmetic expansion: $((x+1))

第一部分按原样打印,然后是一个普通点,最后一部分使用 shell 算术扩展递增: $((x+1))

回答by Fritz G. Mehner

Pure Bash using an array:

使用数组的纯 Bash:

version='1.2.33'
a=( ${version//./ } )                   # replace points, split into array
((a[2]++))                              # increment revision (or other part)
version="${a[0]}.${a[1]}.${a[2]}"       # compose new version

回答by Eedoh

I prefer "cut" command for this kind of things

我更喜欢这种事情的“剪切”命令

major=`echo $version | cut -d. -f1`
minor=`echo $version | cut -d. -f2`
revision=`echo $version | cut -d. -f3`
revision=`expr $revision + 1`

echo "$major.$minor.$revision"

I know this is not the shortest way, but for me it's simplest to understand and to read...

我知道这不是最短的方法,但对我来说,这是最容易理解和阅读的......

回答by Chris J

Yet another shell way (showing there's always more than one way to bugger around with this stuff...):

另一种shell方式(表明总是有不止一种方法可以解决这些问题......):

$ echo 1.2.3 | ( IFS=".$IFS" ; read a b c && echo $a.$b.$((c + 1)) )
1.2.4

So, we can do:

所以,我们可以这样做:

$ x=1.2.3
$ y=`echo $x | ( IFS=".$IFS" ; read a b c && echo $a.$b.$((c + 1)) )`
$ echo $y
1.2.4

回答by geekosaur

I use the shell's own word splitting; something like

我使用shell自己的分词;就像是

oIFS="$IFS"
IFS=.
set -- $version
IFS="$oIFS"

although you need to be careful with version numbers in general due to alphabetic or date suffixes and other annoyingly inconsistent bits. After this, the positional parameters will be set to the components of $version:

尽管由于字母或日期后缀和其他令人讨厌的不一致位,您通常需要小心版本号。在此之后,位置参数将设置为以下组件$version

 = 1
 = 2
 = 13

($IFSis a set of single characters, not a string, so this won't work with a multicharacter field separator, although you can use IFS=.-to split on either .or -.)

($IFS是一组单个字符,而不是字符串,因此这不适用于多字符字段分隔符,尽管您可以使用或IFS=.-进行拆分。).-

回答by bbaja42

Awk makes it quite simple:

awk 让它变得非常简单:

echo "1.2.14" | awk -F \. {'print $1,$2, $3'}will print out 1 2 14.

echo "1.2.14" | awk -F \. {'print $1,$2, $3'}将打印出 1 2 14。

flag -F specifies separator.

标志 -F 指定分隔符。

If you wish to save one of the values:

如果您希望保存其中一个值:

firstVariable=$(echo "1.2.14" | awk -F \. {'print $1'})

firstVariable=$(echo "1.2.14" | awk -F \. {'print $1'})

回答by Sven Driemecker

Inspired by the answer of jlliagreI made my own version which supports version numbers just having a major version given. jlliagre's version will make 1 -> 1.2 instead of 2.

受到jlliagre的回答的启发,我制作了自己的版本,该版本支持仅提供一个主要版本的版本号。jlliagre 的版本将使 1 -> 1.2 而不是 2。

This one is appropriate to both styles of version numbers:

这个适用于两种版本的版本号:

function increment_version()
    local VERSION=""

    local INCREMENTED_VERSION=
    if [[ "$VERSION" =~ .*\..* ]]; then
        INCREMENTED_VERSION="${VERSION%.*}.$((${VERSION##*.}+1))"
    else
        INCREMENTED_VERSION="$((${VERSION##*.}+1))"
    fi

    echo "$INCREMENTED_VERSION"
}

This will produce the following outputs:

这将产生以下输出:

increment_version 1         -> 2 
increment_version 1.2       -> 1.3    
increment_version 1.2.9     -> 1.2.10 
increment_version 1.2.9.101 -> 1.2.9.102

回答by tylo

Small variation on fgm's solution using the builtin readcommand to split the string into an array. Note that the scope of the IFSvariable is limited to the readcommand (so no need to store & restore the current IFSvariable).

使用内置read命令将字符串拆分为数组的fgm 解决方案的小变化。请注意,IFS变量的范围仅限于read命令(因此无需存储和恢复当前IFS变量)。

version='1.2.33'
IFS='.' read -r -a a <<<"$version"
((a[2]++))
printf '%s\n' "${a[@]}" | nl
version="${a[0]}.${a[1]}.${a[2]}"
echo "$version"

See: How do I split a string on a delimiter in Bash?

请参阅:如何在 Bash 中的分隔符上拆分字符串?