【发布时间】:2011-07-11 19:19:53
【问题描述】:
输入:adcheck (CentrifyDC 4.4.3-421)
所需输出:4.4.3
我认为可行的方法:
/usr/share/centrifydc/bin/adcheck --version | sed -n '/Centrify DC /,/-/p'
但这什么也没输出??
谢谢!
【问题讨论】:
标签: sed
输入:adcheck (CentrifyDC 4.4.3-421)
所需输出:4.4.3
我认为可行的方法:
/usr/share/centrifydc/bin/adcheck --version | sed -n '/Centrify DC /,/-/p'
但这什么也没输出??
谢谢!
【问题讨论】:
标签: sed
“您认为可行的方法”的更正版本:
/usr/share/centrifydc/bin/adcheck --version | sed 's|.*CentrifyDC \([0-9\.]*\).*|\1|'
输出:
4.4.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
【讨论】:
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
关于信息,我的sed 尝试不太好。谁知道如何获得与我的perl 脚本相同的行为但使用sed?
sed 's/\([0-9][0-9]*[.][0-9][0-9.]*\)/\n\1/'
如果您认为可以改进这些脚本,请随时发表评论:)
【讨论】:
sed 's/[[:alpha:]|(|[:space:]]//g' | awk -F- '{print $1}' <<< "(CentrifyDC 4.4.3-421)"
输出:4.4.3
使用[:space:] 删除多余的空格。
sed 用于删除不需要的字符,awk -F- 表示使用- 作为字段分隔符
【讨论】:
sed 's/[[:alpha:]([:space:]]//g'
echo | sed | awk太多了,当awk一个人可以做到。
这是 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" '
【讨论】:
仅使用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
【讨论】:
例如,这可以完成工作
wget -V|head -n1|sed 's/[[:alpha:]|(|[:space:]]//g' | awk -F- '{print
> $1}'
【讨论】: