我想从 ld -v
命令中提取版本号,我编写了以下的 sed
表达式:
ld -v | sed -r 's/.+([0-9|\.]+)/\1/'
然而,这输出了版本号的最后一位数字
1
。我期望的结果是2.35.1
。我的正则表达式哪里错了?据我理解,
.+
部分匹配所有字符和空格,([0-9|\.]+)
匹配数字或点,然后捕获此内容。\1
引用捕获的部分。使用GNU grep
的方法如下:
ld -v | grep -Po '[\d.]+' | head -n1
输出:
2.25.1
这里,grep
使用以下选项:
-P
:使用Perl正则表达式。
-o
:仅打印匹配项(每行1个匹配项),而不是整个行。
[\d.]+
:任何数字或实际点号,重复1次或多次。
另请参阅:
grep
手册
perlre - Perl正则表达式
awk
,请尝试以下内容,已在GNU awk
中编写和测试。ld -v |
awk 'match($0,/([0-9]+\.){1,}[0-9]+$/){print substr($0,RSTART,RLENGTH)}'
说明:为上述内容添加详细解释。
ld -v | ##Running ld -v command and sending output to awk program from here.
awk ' ##Starting awk program from here.
match($0,/([0-9]+\.){1,}[0-9]+$/){ ##using match function to match digits followed by dot with 1 ore more occurrences and then digits till last of line.
print substr($0,RSTART,RLENGTH) ##Printing sub string of matched regex which prints from RSTART to till RLENGTH values.
}'
grep
代替,使用-o
选项仅提取匹配的部分:ld -v | grep -Eo '[0-9]+(\.[0-9]+)*$'
请注意,这也将匹配锚定到行的末尾。
模式本身允许其中包含任意数量的.
。通常,版本号有一个MAJOR
、MINOR
和PATCH
——因此最多有2个.
,但在这种情况下匹配更多也没有问题。
您可以更具体一些,只匹配最多两个.
:
ld -v | grep -Eo '[0-9]+(\.[0-9]+){0,2}$'
MINOR
和/或PATCH
-- 例如,版本2.35而不是2.35.1。您可以使用
ld -v | sed -rn 's/.+ ([0-9.]+).*/\1/p'
详情
-r
(或-E
)- 启用 POSIX ERE 表达式语法。
-n
- 抑制默认行输出。
.+ ([0-9.]+).*
- 匹配任何一个或多个字符、一个空格,然后将一个或多个数字和.
捕获到第 1 组中,并匹配任意零个或多个字符。
\1
- 用第 1 组的内容替换匹配。
p
- 打印替换的结果。
ld -v | awk '{print $NF}'
- anubhava+
在.+
中是贪婪的,会匹配所有未被其余正则表达式匹配的字符。结果:只有一个字符被[0-9|\.]+
匹配,因此输出为1
。 - urznow