Parse an RPM name into its components
Solution 1:
You don't need to do any of this; RPM has a query format argument which will let you specify exactly the data you want to receive. It will even output without line endings if you don't specify them.
For instance:
rpm --queryformat "%{NAME} %{VERSION} %{RELEASE} %{ARCH}" -q coreutils
rpm --queryformat "The version of %{NAME} is %{VERSION}\n" -q coreutils
rpm --queryformat "%{NAME} %{VERSION} %{RELEASE} %{ARCH}" -qp file.rpm
The complete list of variables you can use can be obtained with:
rpm --querytags
Note that in the case of RELEASE
, output like 84.el6
is normal and expected, since this is actually how RPM packages are versioned when packaged by or for a distribution.
Solution 2:
I've been told the official way to do what I'm seeking is in Python:
from rpmUtils.miscutils import splitFilename
(n, v, r, e, a) = splitFilename(filename)
I've written a short Python program that does what I need. I will offer the script to the rpmdev project for inclusion.
Solution 3:
I worked out regular expressions that fit all the data I was able to test them with. I had to use a mixture of greedy and non-greedy matches. That said, here is my perl and python versions:
Perl:
#! /usr/bin/perl
foreach (@ARGV) {
($path, $name, $version, $release, $platform,
@junk) = m#(.*/)*(.*)-(.*)-(.*?)\.(.*)(\.rpm)#;
$verrel = $version . '-' . $release;
print join("\t", $path, $name, $verrel, $version, $rev, $platform), "\n";
}
Python:
#! /usr/bin/python
import sys
import re
for x in sys.argv[1:]:
m = re.search(r'(.*/)*(.*)-(.*)-(.*?)\.(.*)(\.rpm)', x)
if m:
(path, name, version, release, platform, _) = m.groups()
path = path or ''
verrel = version + '-' + release
print "\t".join([path, name, verrel, version, release, platform])
else:
sys.stderr.write('ERROR: Invalid name: %s\n' % x)
sys.exit(1)
I'd rather have a regex that comes from the RPM project. The one that I invented above will have to do do for now.
Solution 4:
Rpm files can have some funky file names in extreme cases, but generally you can split the NVR on the hyphens. The catch is the N (name) portion of the NVR may contain hyphens and underscores, but the V(version) and R(release) are guaranteed to not have any extraneous hyphens. So you can start by trimming off the VR portion to derive a Name.
$ RPM=/home/builder/packages/testing-dev/CentOS/6/x86_64/emacs-mercurial-2.8-3.el6.x86_64.rpm
$ echo ${RPM%-*-*}
/home/builder/packages/testing-dev/CentOS/6/x86_64/emacs-mercurial
Building on that you can isolate the Version and Release portion.
echo ${RPM#${RPM%-*-*}-*}
2.8-3.el6.x86_64.rpm
Just split the hyphen again to isolate the part you need. And obviously clean out the arch and rpm file extension strings, which is a given. Just giving you an idea of how it could be approached in bash.
Solution 5:
Use the -q --queryformat options from rpm as said before, if you want to do this on a non installed package you can specify the rpm with the -p
option, like this:
rpm -q -p ./Downloads/polysh-0.4-1.noarch.rpm --queryformat "%{NAME} %{VERSION} %{RELEASE} %{ARCH}\n"
polysh 0.4 1 noarch
e.g.
$ ls ./Downloads/*.rpm
./Downloads/adobe-release-x86_64-1.0-1.noarch.rpm
./Downloads/nautilus-dropbox-1.6.0-1.fedora.x86_64.rpm
./Downloads/playonlinux-yum-4-1.noarch.rpm
./Downloads/skype-4.2.0.11-fedora.i586.rpm
./Downloads/dbview-1.0.4-2.1.x86_64.rpm
./Downloads/openmotif22-libs-2.2.4-192.1.3.x86_64.rpm
./Downloads/polysh-0.4-1.noarch.rpm
gives me
adobe-release-x86_64 1.0 1 noarch
dbview 1.0.4 2.1 x86_64
nautilus-dropbox 1.6.0 1.fc10 x86_64
openmotif22-libs 2.2.4 192.1.3 x86_64
playonlinux-yum 4 1 noarch
polysh 0.4 1 noarch
skype 4.2.0.11 fc16 i586
so just splitting the filename is wrong!
for filename in """<paste list here>""".split():
print splitFilename(filename)
('./Downloads/adobe-release-x86_64', '1.0', '1', '', 'noarch')
('./Downloads/nautilus-dropbox', '1.6.0', '1.fedora', '', 'x86_64')
('./Downloads/playonlinux-yum', '4', '1', '', 'noarch')
('./Downloads/skype', '4.2.0.11', 'fedora', '', 'i586')
('./Downloads/dbview', '1.0.4', '2.1', '', 'x86_64')
('./Downloads/openmotif22-libs', '2.2.4', '192.1.3', '', 'x86_64')
('./Downloads/polysh', '0.4', '1', '', 'noarch')
so pay attention, this is not the correct details of the rpm,
e.g. 1.fedora
is actually 1.fc10
in the rpm.