是否有作为官方 RPM 工具包一部分的名称解析工具?
我有一个文件名列表。每个都是 RPM 包的文件名。我没有实际的包,只有文件名。对于每个我需要提取包名称和版本($NAME 和 $VERSION)。我需要这个的原因是我正在编写一个脚本,然后确保“yum install $VERSION”安装 $VERSION。这是构建包并验证它们是否正确上传的系统的一部分。
文件名列表如下所示:
$ cat /tmp/packages.txt
/home/builder/packages/testing-dev/CentOS/6/x86_64/emacs-mercurial-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/emacs-mercurial-el-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/mercurial-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/mercurial-hgk-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/python-redis-2.8.0-2.el6.noarch.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/redis-2.6.16-1.el6.1.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/sei_dnsmaster-1.0-99.el6.x86_64.rpm
我发现以下代码是执行该任务的 BASH 函数:
function parse_rpm() { RPM=$1;B=${RPM##*/};B=${B%.rpm};A=${B##*.};B=${B%.*};R=${B##*-};B=${B%-*};V=${B##*-};B=${B%-*};N=$B;echo "$N $V $R $A"; }
for i in $(</tmp/packages.txt) ; do
parse_rpm $i
done
有用。大多。有一些例外:
$ parse_rpm CentOS/6/x86_64/sei_dnsmaster-1.0-99.el6.x86_64.rpm
sei_dnsmaster 1.0 99.el6 x86_64
请注意,它没有正确获取版本(应该是 1.0-99)
我想知道 (1) rpmdev 包中是否有一个工具可以正确执行此操作。(2) 如果没有,是否有我可以使用的官方正则表达式。(3) 那个正则表达式的 python 等价物是什么?
提前致谢!
你不需要做任何这些;RPM 有一个查询格式参数,可以让您准确指定要接收的数据。如果您不指定它们,它甚至会输出没有行尾。
例如:
您可以使用的完整变量列表可以通过以下方式获得:
请注意,在 的情况下
RELEASE
,输出 like84.el6
是正常的和预期的,因为这实际上是 RPM 包在由发行版打包或用于发行版时的版本控制方式。有人告诉我,我正在寻找的官方方法是在 Python 中:
我编写了一个简短的 Python 程序来满足我的需要。我会将脚本提供给 rpmdev 项目以供包含。
我制定了适合我能够测试它们的所有数据的正则表达式。我不得不混合使用贪婪和非贪婪匹配。也就是说,这是我的 perl 和 python 版本:
珀尔:
Python:
我宁愿有一个来自 RPM 项目的正则表达式。我上面发明的那个现在必须做。
Rpm 文件在极端情况下可能有一些时髦的文件名,但通常您可以在连字符上拆分 NVR。问题是 NVR 的 N(名称)部分可能包含连字符和下划线,但 V(版本)和 R(版本)保证没有任何无关的连字符。因此,您可以首先修剪 VR 部分以导出名称。
在此基础上,您可以隔离版本和发布部分。
只需再次拆分连字符以隔离您需要的部分。并且显然清除了 arch 和 rpm 文件扩展名字符串,这是给定的。只是让您了解如何在 bash 中处理它。
如前所述,使用 rpm 中的 -q --queryformat 选项,如果要在未安装的包上执行此操作,可以使用该
-p
选项指定 rpm,如下所示:例如
给我
所以只是拆分文件名是错误的!
所以请注意,这不是 rpm 的正确细节,例如
1.fedora
实际上是1.fc10
在 rpm 中。恕我直言,最简单的外壳方式是:
即:反转每一行,仅使用斜线切割第一部分(emanelif),然后使用连字符切割除前两个部分之外的所有部分(即留下ESAELER ,包括emanelif eth fo tser和NOISREV)并将enil反转回来。
使用您的示例文件:
要获得其他部分是阅读cut(1)的练习。
如果您熟悉正则表达式和/或 Perl,那很容易。
或单独的正则表达式:
如果你拆分它,那就是:
[^\-]+
因为连字符在字符组中具有特殊含义而转义)[^\-]+?
([^\-]+?)
([^\-]+?)-
.rpm
):(([^\-]+?)-(.*).rpm$
美元表示“行尾”)m#([^\-]+?)-(.*).rpm$#
完毕 !只需在变量中获取两个部分,
$1
然后$2
评论第一个单行:
我在一个包含许多 rpm 文件的目录中,因此
ls
.perl -p
相当于;这解释了我必须放入一个空字符串
$_
以避免在我提取并自定义打印该行之后 perl 打印回该行。请注意,我可以使用替换来避免这个小“黑客”。您可以利用
dnf info
. 这是一个获取值并设置为变量的示例 Bash 脚本:即使未安装软件包,它也会给出结果。
到目前为止,最简单的方法是创建一个可以做一件事的正则表达式,工作;-) Substring Regex w're disc.:
那是 perl 中的子字符串正则表达式!
例子:
输出:
4.8.5-36.0.1.el7_6.2.x86_64
所以版本是对的。正则表达式在一行中涵盖了 99.9% 的 RPM 包名称;-)
简短说明:(?:) 非捕获组(我不想要这部分 -> 使用它来提高速度。总是)
\w+:单词字符(包括_)
? 可选匹配
\S+:非空格字符
{1,} 不捕获-匹配整个组 1 个或多个
Worx 为你和我!