sed:从字符串中提取版本号

时间:2011-07-11 19:19:54

标签: sed

输入:adcheck (CentrifyDC 4.4.3-421)

所需的输出:4.4.3

我认为会起作用:

/usr/share/centrifydc/bin/adcheck --version | sed -n '/Centrify DC /,/-/p'

但是没有输出?

谢谢!

7 个答案:

答案 0 :(得分:5)

sed 's/[[:alpha:]|(|[:space:]]//g' | awk -F- '{print $1}' <<< "(CentrifyDC 4.4.3-421)"

输出:4.4.3

使用[:space:]删除额外空格。

sed用于删除不需要的字符,awk -F-表示使用-作为字段分隔符

答案 1 :(得分:3)

您的解决方案不起作用,因为您尝试使用地址来选择一条线,但地址只选择一堆线。您的代码/Centrify DC /,/-/p会在包含Centrify DC的一行和包含-的另一行之间打印所有行。它只在一行内部不起作用,但是

你想要的是删除除了版本号之外的所有内容。我建议你将版本号分组并用它替换该行的所有内容:

$ echo "adcheck (CentrifyDC 4.4.3-421)" | sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/'
4.4.3

在这里,我们将版本号放在一个\([0-9]*\.[0-9]*\.[0-9]*\)的组中,并将所有行替换为组(由\1引用)。

如果您的输入有多行,则可能需要一些隧道:

$ cat file
adcheck (CentrifyDC 4.4.3-421)
another line
still another line
$ sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/' file
4.4.3
another line
still another line

在这种情况下,将-n标志传递给sed以禁止默认打印。然后,为s///命令(例如/adcheck (CentrifyDC /)提供一个地址,以保证替换只发生在与地址匹配的行中。最后将p标志添加到s///命令 - 它将在替换后打印该行:

$  sed -n '/adcheck (CentrifyDC /s/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/p' file
4.4.3

答案 2 :(得分:3)

更正版“你认为会起作用”:

/usr/share/centrifydc/bin/adcheck --version | sed 's|.*CentrifyDC \([0-9\.]*\).*|\1|'

<强>输出:

4.4.3

答案 3 :(得分:3)

单行脚本

perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' YOURFILE.TXT

或更长一些但处理多个版本:

perl -nle 'print $v if ($v)=/([0-9]+([.][0-9]+)+)/' YOURFILE.TXT

使用第一个命令行的示例

$> V=$(perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'<<<'adcheck (CentrifyDC 4.4.3-421)')
$> echo "$V"
4.4.3

$> V=$(perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' <<< 'dos2unix-8.2.3-beta.zip')
$> echo "$V"
8.2.3

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

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

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

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

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

$> perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' /etc/issue
13.04

注意:第一个命令行提取没有最终回车的版本(我的意思是\n)。如果这是一个问题,请使用第二个版本或在echo中包装第一个命令行:

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

不幸的是,如果有多行包含版本号,则会连接这些版本号:

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

4.8.44.10.54.10.4

为了每行提取一个版本,必须更改单行脚本:

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

示例:

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

要仅提取第一个版本号并追加回车(我的意思是新行\n),我建议:

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

示例:

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

有关信息,我的尝试效果不佳。谁知道如何使用perl脚本获取与sed脚本相同的行为?

sed 's/\([0-9][0-9]*[.][0-9][0-9.]*\)/\n\1/'

如果您认为可以改进这些脚本,请随时发表评论:)

答案 4 :(得分:1)

以下是Perl的解决方案:

echo "adcheck (CentrifyDC 4.4.3-421)" | perl -ne 'm/adcheck \(CentrifyDC (.*?)\)/; print "$1\n" '
/usr/share/centrifydc/bin/adcheck --version | perl -ne 'm/adcheck \(CentrifyDC (.*?)\)/; print "$1\n" '

答案 5 :(得分:1)

仅使用awk的另一种方法:

$ echo "adcheck (CentrifyDC 4.4.3-421)" | awk '{sub(/-.*/,"",$3);print $3}'
4.4.3

......或者可能是cut

的组合
$ echo "adcheck (CentrifyDC 4.4.3-421)" | cut -d' ' -f3 | cut -d'-' -f1
4.4.3

答案 6 :(得分:0)

例如,这可以完成工作

wget -V|head -n1|sed 's/[[:alpha:]|(|[:space:]]//g' | awk -F- '{print
> $1}'