bash 从字符串中提取版本号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16817646/
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-18 05:32:30  来源:igfitidea点击:

Extract version number from a string

bashshellunixscriptingsed

提问by mles

I have a string with components and version numbers:

我有一个包含组件和版本号的字符串:

data-c(kuh-small1);divider-bin-1.4.4;divider-conf-1.3.3-w(1,16);storage-bin-1.5.4;storage-conf-1.5.0-w(1);worker-bin-4.5.1;worker-conf-4.4.1-c(kuh)-win2

data-c(kuh-small1);divider-bin-1.4.4;divider-conf-1.3.3-w(1,16);storage-bin-1.5.4;storage-conf-1.5.0-w(1);worker-bin-4.5.1;worker-conf-4.4.1-c(kuh)-win2

For a shell script, I need to extract the version number of the divider binary. So I need to yield:

对于 shell 脚本,我需要提取分隔符二进制文件的版本号。所以我需要屈服:

1.4.4

1.4.4

What would be a good way to do this? with sed?

这样做的好方法是什么?用sed?

回答by fedorqui 'SO stop harming'

Following Kent's answers, this can work:

按照肯特的回答,这可以工作:

grep -Po '(?<=divider-bin-)\d.\d.\d'

and even better:

甚至更好:

grep -Po '(?<=divider-bin-)[^;]+'

it greps from divider-bin-until it find the ;character. This way any NNN.NNN. ... . NNNformat will work (no matter how many blocks of NN).

它从divider-bin-直到找到;字符为止。这样任何NNN.NNN. ... . NNN格式都可以工作(无论有多少块NN)。

Test:

测试:

$ echo "data-c(kuh-small1);divider-bin-1.4.4;divider-conf-1.3.3-w(1,16);storage-bin-1.5.4;storage-conf-1.5.0-w(1);worker-bin-4.5.1;worker-conf-4.4.1-c(kuh)-win2" | grep -Po '(?<=divider-bin-)[^;]+'
1.4.4
$ echo "data-c(kuh-small1);divider-bin-1.4;divider-conf-1.3.3-w(1,16);storage-bin-1.5.4;storage-conf-1.5.0-w(1);worker-bin-4.5.1;worker-conf-4.4.1-c(kuh)-win2" | grep -Po '(?<=divider-bin-)[^;]+'
1.4

回答by olibre

This general answer should work in all cases

这个通用答案应该适用于所有情况

I use one of these three one-line perlcommands depending on the expected input string:

我根据预期的输入字符串使用这三个单行perl命令之一:

  1. The input string always contain one single version

    perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' 
    
  2. To extract several versions (several lines)

    perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}'
    
  3. To extract one single version (the first one) in all cases

    perl -pe 'if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v\n";exit}$_=""'
    
  1. 输入字符串始终包含一个版本

    perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' 
    
  2. 提取多个版本(几行)

    perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}'
    
  3. 在所有情况下提取一个单一版本(第一个)

    perl -pe 'if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v\n";exit}$_=""'
    


1. The simplest

1.最简单的

The first command line do not embed the final newline:

第一个命令行不嵌入最后的换行符:

> gcc --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
5.3.1

> bash --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
4.2.46

> perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' <<< 'A2 33. Z-0.1.2.3.4..5'
0.1.2.3.4

> uname -a | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
3.10.0

> lsb_release | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
4.1

Store the version within a shell variable:

将版本存储在 shell 变量中:

> v=$( gcc --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' )
> echo "GCC version is '$v'"
GCC version is '5.3.1'

But fails for multi version numbers:

但对于多版本号失败:

> gwenview --version
Qt: 4.8.5
KDE Development Platform: 4.14.8
Gwenview: 4.10.4

> gwenview --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
4.8.54.14.84.10.4

2. Extract one version per line

2.每行提取一个版本

> gwenview --version | perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}' 
4.8.4
4.14.8
4.10.4

> mvn --version
Apache Maven 3.0.4
Maven home: /usr/share/maven
Java version: 1.7.0_25, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-7-openjdk-amd64/jre
Default locale: fr_FR, platform encoding: UTF-8
OS name: "linux", version: "3.11.0-13-generic", arch: "amd64", family: "unix"

> mvn --version | perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}'
3.0.4
1.7.0
3.11.0

3. Extract the first version only

3. 只解压第一个版本

> gwenview --version | perl -pe 'if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v\n";exit}$_=""'
4.8.5

Create an alias:

创建别名:

> alias extractor='perl -pe '\''if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v";exit}$_=""'\'''

or if you use a recent bash:

或者如果您使用最近的bash

> alias extractor=$'perl -pe \'if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v";exit}$_=""\''

> v=$( mvn --version | extractor )
> echo "The maven version is '$v'"
The maven version is '3.0.4'

回答by trey85stang

sed can handle this easily....

sed 可以轻松处理这个问题....

string="ata-c(kuh-small1);divider-bin-1.4.4;divider-conf-1.3.3-w(1,16);storage-bin-1.5.4;storage-conf-1.5.0-w(1);worker-bin-4.5.1;worker-conf-4.4.1-c(kuh)-win2"

echo $string | sed "s/^.*divider-bin-\([0-9.]*\).*//"
1.4.4

There are a few other things you can do to tighten it up... such as stop grabbing the version number when you reach the ";"

您还可以采取其他一些措施来收紧它……例如,当您到达“;”时停止获取版本号。

sed "s/^.*divider-bin-\([^;]*\).*//"

回答by michas

You can also use perl:

你也可以使用 perl:

perl -wne '/divider-bin-(.+?);/ and print "\n"

回答by NeronLeVelu

sed -n "s/.*;divider-bin-\([0-9][^;]*\);.*//p"

infos is between ;divider-bin-and next ;and start with a digit. This is to ensur that no Other-divider-bin-or divider-bin-and-hex-will interfere with your request. Also, return empty string if not find. to be exhaustif (assuming version is only digit and dot)

infos 介于;divider-bin-和 next之间,;并以数字开头。这是为了确保不会Other-divider-bin-divider-bin-and-hex-将干扰您的请求。此外,如果找不到,则返回空字符串。要穷尽(假设版本只有数字和点)

sed -n "s/.*;divider-bin-\([0-9.]\{1,\}\)\([^0-9.;][^;]*\)*;.*//p"