我有一个file.xml,它是这样组成的:
...some xml text here...
<Version>1.0.13-alpha</Version>
...some xml text here...我需要提取以下信息:
我认为实现这一点的最干净的方法是使用grep命令进行正则表达式:
<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>我已经用regex101检查了这个正则表达式的正确性,实际上它似乎正确地捕获了我正在寻找的三个字段。但问题来了,因为我不知道如何打印这些字段。
cat file.xml | grep "<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>" -oP这个命令打印整个行,所以它是无用的。
在这个站点上已经写了几篇关于这个主题的文章,所以我也尝试使用bash本机regex支持,结果很糟糕:
regex="<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>"
txt=$(cat file.xml)
[[ "$txt" =~ $regex ]] --> it fails!
echo "${BASH_REMATCH[*]}"对不起,我想不出该怎么解决这个问题。预期的产出应是:
1.0
13
-alpha发布于 2020-11-12 18:00:32
您可以使用与您的read + sed解决方案类似的正则表达式:
read -r major minor suffix < <(
sed -nE 's~.*<Version>([0-9]+\.[0-9]+)\.([0-9]+)(-[^<]*)</Version>.*~\1 \2 \3~p' file.xml
)检查变量内容:
declare -p major minor suffix
declare -- major="1.0"
declare -- minor="13"
declare -- suffix="-alpha"以下几点:
\d中使用-P (perl)模式,就不能使用grepgrep命令不返回捕获组发布于 2020-11-12 19:09:22
使用这个Perl一行程序:
perl -lne 'print for m{<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>};' file.xml示例:
echo '<Version>1.0.13-alpha</Version>' | perl -lne 'print for m{<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>};'输出:
1.0
13
-alphaPerl一行程序使用以下命令行标志:
-e:告诉Perl在行中查找代码,而不是在文件中。
-n:每次循环输入一行,默认情况下将其分配给$_。
-l:在执行代码行之前,先去掉输入行分隔符(默认情况下是*NIX上的"\n"),然后在打印时追加它。
还请参见:
https://stackoverflow.com/questions/64809125
复制相似问题