RegEx用于解析Fedora / Red Hat软件包的软件包名称、软件包版本(包括发布版本)

fsi0uk1n  于 2023-10-22  发布在  其他
关注(0)|答案(5)|浏览(106)

我的目标是正确解析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)。所以我不会安装perlpython,只安装了一组最小的命令,如:catsedawkgrep等。

pinkon5k

pinkon5k1#

如果你可以使用Perl:

perl -pe 's/(.*?)-([0-9].*?)\.[^0-9].*/pkg: $1\tversion: $2/' << EOF
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
EOF

sed版本,假设包名中没有@:

sed -E 's/\.[^0-9].*$// # Remove everything after version
        s/(-[0-9].*)/@\1/ # Insert @ before version
        s/([^@]+)@-(.*)/pkg: \1\tversion: \2/' << EOF
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
EOF
tnkciper

tnkciper2#

使用您显示的示例,请尝试以下Perl单行解决方案。这里使用正则表达式^(.*?)-([0-9]+[a-zA-Z]*(?:\.[0-9]+)*(?:-[a-zA-Z0-9]+)?),它创建了两个捕获组,我们使用它们来打印值,同时根据需要的输出在这里执行替换。

perl -pe 's/^(.*?)-([0-9]+[a-zA-Z]*(?:\.[0-9]+)*(?:-[a-zA-Z0-9]+)?)/pkg: $1\tversion: $2/'  Input_file
643ylb08

643ylb083#

如果你的容器有rpm命令,那么它提供了最安全的方式来做你想做的事情(至少在另一个答案中有描述)。
如果您没有rpm命令,那么您可以根据Format of the RPM File中记录的RPM包命名标准,轻松安全地执行您想要的操作。格式为name-version-release.architecture(NVRA)。由于内部连字符(破折号,-字符)只能出现在name中,并且architecture从不包含点,因此可以直接将软件包名称解析为各个部分。
便携式(无-Esed解决方案是:

sed 's/\(.*\)-\(.*-[^.]*\).*/pkg: \1 version: \2/' pkgs.txt

它也可以通过标准的shell字符串操作来完成。我用bashdash测试了这个Shellcheck-干净的代码:

#! /bin/sh -

while read -r nvra || [ -n "$nvra" ]; do
    nv=${nvra%-*}
    ra=${nvra##*-}
    n=${nv%-*}
    v=${nv##*-}
    printf 'pkg: %s version: %s-%s\n' "$n" "$v" "${ra%%.*}"
done <pkgs.txt

但是,如果pkgs.txt文件很大(我猜超过1000行),纯shell代码会非常慢。

q1qsirdb

q1qsirdb4#

在这里添加一个awk答案,因为OP说perl可能不在他们的容器中。使用GNU awk

  • 根据所示样品制作(\\+|\\.)el[0-9]+(\\.[0-9]*)*田间隔离带。
  • 然后使用match函数匹配regex -([0-9]+[a-zA-Z]*)([^-]+)(-[a-zA-Z0-9]+)?,以获得这里的版本值。
  • 然后再次使用match函数在版本之前获取值,如果awk支持延迟匹配,会更容易做到:)
awk -F'(\\+|\\.)el[0-9]+(\\.[0-9]*)*' '
match($1,/-([0-9]+[a-zA-Z]*)([^-]+)(-[a-zA-Z0-9]+)?/,arr){
   val=arr[1] arr[2] arr[3]
}
match($1,val){
   print "pkg: " substr($1,1,RSTART-2) "\tversion: " val
}
'  Input_file
  • 或 * 在awk一个之后使用column命令以获得好看格式的输出。
awk -F'(\\+|\\.)el[0-9]+(\\.[0-9]*)*' '
match($1,/-([0-9]+[a-zA-Z]*)([^-]+)(-[a-zA-Z0-9]+)?/,arr){
  val=arr[1] arr[2] arr[3]
}
match($1,val){
  print "pkg: " substr($1,1,RSTART-2) "\tversion: " val
}
' Input_file | column -t
mitkmikd

mitkmikd5#

使用RedHat或Fedora提供的rpm包管理器返回名称和版本无疑比使用Regex解析包名称更可靠。
范例:

#!/bin/sh
for pkg in
  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
do
  rpm -qp --queryformat 'pkg: %{NAME} version: %{VERSION}' "$pkg.rpm"
done

或者,如果所有的文件名都是.rpm,则甚至不需要循环:

rpm -qp --queryformat 'pkg: %{NAME} version: %{VERSION}' \
  python39-3.9.16-1.module+el8.8.0+18968+3d7b19f0.1.x86_64.rpm \
  python3.11-3.11.2-2.el9_2.2.aarch64.rpm \
  glibc-2.34-60.el9.aarch64.rpm \
  glib2-2.68.4-6.el9.aarch64.rpm \
  langpacks-core-font-en-3.0-16.el9.noarch.rpm \
  p11-kit-trust-0.24.1-2.el9.aarch64.rpm \
  tzdata-2023c-1.el9.noarch.rpm

相关问题