bash + 如何从rpm中获取版本
bash + how to capture the version from rpm
这是我尝试获取Kafka版本时的方式
rpm -qa | grep "^kafka_"
kafka_2_6_5_0_292-1.0.0.2.6.5.0-292.noarch
Kafka 版本是 1.0 ,所以我做了以下为了削减 Kafka 版本
rpm -qa | grep "^kafka_" | sed s'/-/ /g' | awk '{print }' | cut -c 1-3
1.0 <----- results
上面的cli好像语法不够优雅和冗长
我们可以做得更好吗,也许使用 Perl 或 Python 一个线性命令?
您可以使用单个 awk
:
rpm -qa |
awk -F- '/^kafka_/ && split(, a, /\./) >= 1 {print a[1] "." a[2]}'
1.0
这个sed
有效吗?
rpm -qa | grep '^kafka_' | sed 's/[a-z0-9_]*-\(...\).*//'
重构您的代码
rpm -qa | grep "^kafka_" | sed s'/-/ /g' | awk '{print }' | cut -c 1-3
第一步:使用AWK
的FS
(字段分隔符)代替sed
中的预处理
rpm -qa | grep "^kafka_" | awk 'BEGIN{FS="-"}{print }' | cut -c 1-3
第 2 步:将 {print }
操作注册到匹配描述的行,而不是使用 grep
过滤它
rpm -qa | awk 'BEGIN{FS="-"}/^kafka_/{print }' | cut -c 1-3
第三步:使用AWK
的substr
函数代替cut -c
rpm -qa | awk 'BEGIN{FS="-"}/^kafka_/{print substr(,1,3)}'
免责声明:我的回答假设您希望行为与原始代码完全相同,即使可能出乎意料,即它确实获得版本部分的前 3 个字符,无论第二部分有多少数字,例如 1.15.0.2.6.5.0-292
它确实产生 1.1
if k=$(rpm -qa | grep "^kafka_")
then
if [[ ${k#*-} =~ ^[0-9]+[.][0-9]+ ]]
then
k_version=$BASH_REMATCH
else
echo "can not determine kafka version from '$k'"
fi
else
echo "No kafka in rpm"
fi
这里的想法是删除从版本字符串到破折号的所有内容,然后使用正则表达式获取版本部分。
使用您显示的示例,请尝试以下 awk
代码。简单的解释是,将 rpm -qa
命令的输出作为标准输入发送到 awk
代码。在 awk
程序中设置字段 aeparator 为 -
或 .
和 OFS
为 .
。然后在主程序中检查一行是否从 kafka_
开始,然后按照显示的示例打印它的第二个和第三个字段。
rpm -qa | awk -F'-|\.' 'BEGIN{OFS="."} /^kafka_/{print ,}'
这完全可以用 (GNU) grep
.
grep -oP '^kafka_[^-]*-\K\d+\.\d+'
例如,
$ echo kafka_2_6_5_0_292-1.0.0.2.6.5.0-292.noarch | grep -oP '^kafka_[^-]*-\K\d+\.\d+'
1.0
但是既然你问的是 Perl 或 Python,
perl -ne'print "$&\n" if /^kafka_[^-]*-\K\d+\.\d+/'
拜托,许多关于打包 return 不同格式数据的工具。
rpm
命令是一个工具,其输出在工具版本和系统之间是不同的(GNU/Linux、AIX...)...
因此,当您在脚本中使用 rpm
命令时,切勿单独使用 -q
选项。
使用 --queryformat
(简称 --qf
,有两个 -
)来指定输出。
有关详细信息,请参阅 man rpm
。
示例:
$ rpm -q --qf "%{NAME}:%{VERSION}" firefox
firefox:91.0.1
标签是这样指定的:%{...}
标签名称通过rpm --querytags
命令获取。
包名 unknow/partial 的示例:
$ rpm -qa --qf "%{NAME}:%{VERSION}\n" | grep '^kernel'
kernel-srpm-macros:1.0
kernel-headers:5.13.3
kernel-core:5.13.12
kernel-modules:5.13.12
kernel:5.13.12
kernel-modules-extra:5.13.12
注:
\n
用于分隔所有包裹'name:version'情侣
这是我尝试获取Kafka版本时的方式
rpm -qa | grep "^kafka_"
kafka_2_6_5_0_292-1.0.0.2.6.5.0-292.noarch
Kafka 版本是 1.0 ,所以我做了以下为了削减 Kafka 版本
rpm -qa | grep "^kafka_" | sed s'/-/ /g' | awk '{print }' | cut -c 1-3
1.0 <----- results
上面的cli好像语法不够优雅和冗长
我们可以做得更好吗,也许使用 Perl 或 Python 一个线性命令?
您可以使用单个 awk
:
rpm -qa |
awk -F- '/^kafka_/ && split(, a, /\./) >= 1 {print a[1] "." a[2]}'
1.0
这个sed
有效吗?
rpm -qa | grep '^kafka_' | sed 's/[a-z0-9_]*-\(...\).*//'
重构您的代码
rpm -qa | grep "^kafka_" | sed s'/-/ /g' | awk '{print }' | cut -c 1-3
第一步:使用AWK
的FS
(字段分隔符)代替sed
rpm -qa | grep "^kafka_" | awk 'BEGIN{FS="-"}{print }' | cut -c 1-3
第 2 步:将 {print }
操作注册到匹配描述的行,而不是使用 grep
rpm -qa | awk 'BEGIN{FS="-"}/^kafka_/{print }' | cut -c 1-3
第三步:使用AWK
的substr
函数代替cut -c
rpm -qa | awk 'BEGIN{FS="-"}/^kafka_/{print substr(,1,3)}'
免责声明:我的回答假设您希望行为与原始代码完全相同,即使可能出乎意料,即它确实获得版本部分的前 3 个字符,无论第二部分有多少数字,例如 1.15.0.2.6.5.0-292
它确实产生 1.1
if k=$(rpm -qa | grep "^kafka_")
then
if [[ ${k#*-} =~ ^[0-9]+[.][0-9]+ ]]
then
k_version=$BASH_REMATCH
else
echo "can not determine kafka version from '$k'"
fi
else
echo "No kafka in rpm"
fi
这里的想法是删除从版本字符串到破折号的所有内容,然后使用正则表达式获取版本部分。
使用您显示的示例,请尝试以下 awk
代码。简单的解释是,将 rpm -qa
命令的输出作为标准输入发送到 awk
代码。在 awk
程序中设置字段 aeparator 为 -
或 .
和 OFS
为 .
。然后在主程序中检查一行是否从 kafka_
开始,然后按照显示的示例打印它的第二个和第三个字段。
rpm -qa | awk -F'-|\.' 'BEGIN{OFS="."} /^kafka_/{print ,}'
这完全可以用 (GNU) grep
.
grep -oP '^kafka_[^-]*-\K\d+\.\d+'
例如,
$ echo kafka_2_6_5_0_292-1.0.0.2.6.5.0-292.noarch | grep -oP '^kafka_[^-]*-\K\d+\.\d+'
1.0
但是既然你问的是 Perl 或 Python,
perl -ne'print "$&\n" if /^kafka_[^-]*-\K\d+\.\d+/'
拜托,许多关于打包 return 不同格式数据的工具。
rpm
命令是一个工具,其输出在工具版本和系统之间是不同的(GNU/Linux、AIX...)...
因此,当您在脚本中使用 rpm
命令时,切勿单独使用 -q
选项。
使用 --queryformat
(简称 --qf
,有两个 -
)来指定输出。
有关详细信息,请参阅 man rpm
。
示例:
$ rpm -q --qf "%{NAME}:%{VERSION}" firefox
firefox:91.0.1
标签是这样指定的:%{...}
标签名称通过rpm --querytags
命令获取。
包名 unknow/partial 的示例:
$ rpm -qa --qf "%{NAME}:%{VERSION}\n" | grep '^kernel'
kernel-srpm-macros:1.0
kernel-headers:5.13.3
kernel-core:5.13.12
kernel-modules:5.13.12
kernel:5.13.12
kernel-modules-extra:5.13.12
注:
\n
用于分隔所有包裹'name:version'情侣