bash - 打印正则表达式捕获的组
bash - print regex captured groups
我有一个file.xml这么沉着:
...some xml text here...
<Version>1.0.13-alpha</Version>
...some xml text here...
我需要提取以下信息:
- mayor_and_minor_release_number --> 1.0
- patch_number --> 13
- 后缀 --> -alpha
我认为最简洁的方法是使用带有 grep 命令的正则表达式:
<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>
我已经用 regex101 检查了这个正则表达式的正确性,实际上它似乎正确地捕获了我正在寻找的 3 个字段。但是问题来了,因为我不知道如何打印这些字段。
cat file.xml | grep "<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>" -oP
这个命令打印整行,所以它没什么用。
这个网站上有几篇文章是关于这个主题的,所以我也尝试使用 bash native
正则表达式支持,结果不佳:
regex="<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>"
txt=$(cat file.xml)
[[ "$txt" =~ $regex ]] --> it fails!
echo "${BASH_REMATCH[*]}"
抱歉,我不知道如何解决这个问题。所需的输出应为:
1.0
13
-alpha
您可以使用此 read + sed
解决方案,其正则表达式与您的类似:
read -r major minor suffix < <(
sed -nE 's~.*<Version>([0-9]+\.[0-9]+)\.([0-9]+)(-[^<]*)</Version>.*~ ~p' file.xml
)
检查变量内容:
declare -p major minor suffix
declare -- major="1.0"
declare -- minor="13"
declare -- suffix="-alpha"
几点:
- 如果不在
grep
中使用 -P
(perl) 模式,则无法使用 \d
grep
命令不 return 捕获组
使用这个 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
-alpha
Perl 单行代码使用这些命令行标志:
-e
: 告诉 Perl 查找内联代码,而不是在文件中。
-n
:一次循环输入一行,默认分配给 $_
。
-l
: 在执行内联代码之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches
我有一个file.xml这么沉着:
...some xml text here...
<Version>1.0.13-alpha</Version>
...some xml text here...
我需要提取以下信息:
- mayor_and_minor_release_number --> 1.0
- patch_number --> 13
- 后缀 --> -alpha
我认为最简洁的方法是使用带有 grep 命令的正则表达式:
<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>
我已经用 regex101 检查了这个正则表达式的正确性,实际上它似乎正确地捕获了我正在寻找的 3 个字段。但是问题来了,因为我不知道如何打印这些字段。
cat file.xml | grep "<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>" -oP
这个命令打印整行,所以它没什么用。
这个网站上有几篇文章是关于这个主题的,所以我也尝试使用 bash native 正则表达式支持,结果不佳:
regex="<Version>(\d+\.\d+)\.(\d+)([\w-]+)?<\/Version>"
txt=$(cat file.xml)
[[ "$txt" =~ $regex ]] --> it fails!
echo "${BASH_REMATCH[*]}"
抱歉,我不知道如何解决这个问题。所需的输出应为:
1.0
13
-alpha
您可以使用此 read + sed
解决方案,其正则表达式与您的类似:
read -r major minor suffix < <(
sed -nE 's~.*<Version>([0-9]+\.[0-9]+)\.([0-9]+)(-[^<]*)</Version>.*~ ~p' file.xml
)
检查变量内容:
declare -p major minor suffix
declare -- major="1.0"
declare -- minor="13"
declare -- suffix="-alpha"
几点:
- 如果不在
grep
中使用 grep
命令不 return 捕获组
-P
(perl) 模式,则无法使用 \d
使用这个 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
-alpha
Perl 单行代码使用这些命令行标志:
-e
: 告诉 Perl 查找内联代码,而不是在文件中。
-n
:一次循环输入一行,默认分配给 $_
。
-l
: 在执行内联代码之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches