我的目标是正确解析Fedora或Red Hat软件包的软件包名称和软件包版本(包括版本号),如下所示:
python39-3.9.16-1.module+el8.8.0+18968+3d7b19f0.1.x86_64
python3.11-3.11.2-2.el9_2.2.aarch64
glibc-2.34-60.el9.aarch64
glib2-2.68.4-6.el9.aarch64
langpacks-core-font-en-3.0-16.el9.noarch
p11-kit-trust-0.24.1-2.el9.aarch64
tzdata-2023c-1.el9.noarch
预期结果:
pkg: python39 version: 3.9.16-1
pkg: python3.11 version: 3.11.2-2
pkg: glibc version: 2.34-60
pkg: glib2 version: 2.68.4-6
pkg: langpacks-core-font-en version: 3.0-16
pkg: p11-kit-trust: version: 0.24.1-2
pkg: tzdata version: 2023c-1
以下是我的尝试:
echo -e "python39-3.9.16-1.module+el8.8.0+18968+3d7b19f0.1.x86_64\npython3.11-3.11.2-2.el9_2.2.aarch64\nglibc-2.34-60.el9.aarch64\nglib2-2.68.4-6.el9.aarch64\nlangpacks-core-font-en-3.0-16.el9.noarch\np11-kit-trust-0.24.1-2.el9.aarch64\ntzdata-2023c-1.el9.noarch" > pkgs.txt
cat pkgs.txt | sed -E 's/([^-]*)-([0-9]+(\.[0-9]+)*(-[0-9]+)?)([^0-9].*)?/pkg: \1\tversion: \2/'
我得到了:
pkg: python39 version: 3.9.16-1
pkg: python3.11 version: 3.11.2-2
pkg: glibc version: 2.34-60
pkg: glib2 version: 2.68.4-6
langpacks-core-font-pkg: en version: 3.0-16
p11-kit-pkg: trust version: 0.24.1-2
pkg: tzdata version: 2023
请帮助我修复/改进正则表达式,以正确解析软件包名称和软件包版本
UPDATE我将在安装了最少操作系统包的容器中执行此命令(类似于ubi-minimal
)。所以我不会安装perl
和python
,只安装了一组最小的命令,如:cat
、sed
、awk
、grep
等。
5条答案
按热度按时间pinkon5k1#
如果你可以使用Perl:
sed
版本,假设包名中没有@:tnkciper2#
使用您显示的示例,请尝试以下Perl单行解决方案。这里使用正则表达式
^(.*?)-([0-9]+[a-zA-Z]*(?:\.[0-9]+)*(?:-[a-zA-Z0-9]+)?)
,它创建了两个捕获组,我们使用它们来打印值,同时根据需要的输出在这里执行替换。643ylb083#
如果你的容器有
rpm
命令,那么它提供了最安全的方式来做你想做的事情(至少在另一个答案中有描述)。如果您没有
rpm
命令,那么您可以根据Format of the RPM File中记录的RPM包命名标准,轻松安全地执行您想要的操作。格式为name-version-release.architecture
(NVRA)。由于内部连字符(破折号,-
字符)只能出现在name
中,并且architecture
从不包含点,因此可以直接将软件包名称解析为各个部分。便携式(无
-E
)sed
解决方案是:它也可以通过标准的shell字符串操作来完成。我用
bash
和dash
测试了这个Shellcheck-干净的代码:但是,如果
pkgs.txt
文件很大(我猜超过1000行),纯shell代码会非常慢。q1qsirdb4#
在这里添加一个
awk
答案,因为OP说perl
可能不在他们的容器中。使用GNUawk
。(\\+|\\.)el[0-9]+(\\.[0-9]*)*
田间隔离带。match
函数匹配regex-([0-9]+[a-zA-Z]*)([^-]+)(-[a-zA-Z0-9]+)?
,以获得这里的版本值。match
函数在版本之前获取值,如果awk
支持延迟匹配,会更容易做到:)awk
一个之后使用column
命令以获得好看格式的输出。mitkmikd5#
使用RedHat或Fedora提供的
rpm
包管理器返回名称和版本无疑比使用Regex解析包名称更可靠。范例:
或者,如果所有的文件名都是
.rpm
,则甚至不需要循环: