8

The output format from the command rpm -qa looks like the following:

abrt-1.1.14-1.fc14.x86_64
abrt-addon-ccpp-1.1.14-1.fc14.x86_64
abrt-addon-kerneloops-1.1.14-1.fc14.x86_64
abrt-addon-python-1.1.14-1.fc14.x86_64
abrt-desktop-1.1.14-1.fc14.x86_64
abrt-gui-1.1.14-1.fc14.x86_64
abrt-libs-1.1.14-1.fc14.x86_64
abrt-plugin-bugzilla-1.1.14-1.fc14.x86_64
abrt-plugin-logger-1.1.14-1.fc14.x86_64
abrt-plugin-runapp-1.1.14-1.fc14.x86_64

Can anyone tell me how to reliably remove the version, release, and arch part so that I end up with

abrt
abrt-addon-ccpp
abrt-addon-kerneloops
abrt-addon-python
abrt-desktop
abrt-gui
abrt-libs
abrt-plugin-bugzilla
abrt-plugin-logger
abrt-plugin-runapp

I would rather avoid trying to construct a regular expression for sed, because I expect it to be complicated in order to support names like super-3d-editor-0.1-1.fc14.x86_64 or similar. I am sure I am not the first person wanting such filtering, therefore I ask here to check if there already exists some solution.

Update: The "or similar" note above implies some knowledge about what rpm package names looks like. Most of them are "nice looking" like the ones presented above, but there are also entries with more diverse numbering schemes:

fxload-2002_04_11-9.fc12.x86_64
GitPython-0.2.0-0.3.beta1.fc14.noarch
ModemManager-0.4-4.git20100720.fc14.x86_64
python-peak-rules-0.5a1.dev-12.a1.dev.20100803svn2646.fc14.noarch
pytz-2010h-3.fc14.noarch

Also note that there exists packages where a version number is part of the name like

java-1.5.0-gcj-1.5.0.0-34.fc14.x86_64
java-1.6.0-openjdk-1.6.0.0-49.1.9.3.fc14.x86_64
java-1.6.0-openjdk-devel-1.6.0.0-49.1.9.3.fc14.x86_64

and there are even a few where the release/arch is missing (these might be hard to handle, and I can accept failure to handle these)

bouml-doc-4.3.2-3.noarch
fedora-release-14-1.noarch
glibc-2.12.90-21.i686
basesystem-10.0-3.noarch
ivtv-firmware-20080701-20.noarch
gpg-pubkey-97a1071f-4c49d6fe

That is why I asked for a reliable way to do this; I knew that creating an approximate sed regex would be possible but it was bound to fail to handle many lines.


(I know that it is possible to format the output from rpm with --queryformat, however that will not be of help to me because I want to compare which packages I have installed today by comparing with a rpm -qa listing that was generated a year ago.)

2
  • You mean the version, release, and the arch. Dec 17, 2010 at 21:56
  • Yes, I do. I will update the question.
    – hlovdal
    Dec 17, 2010 at 22:09

7 Answers 7

6

Since you're already pooched, you need to carve off the crap from last year. If it's consistent enough to always be in the stock format, here you go:

#!/usr/bin/python

import sys

for line in sys.stdin:
  if line.startswith('gpg-pubkey-'):
    continue # We don't care about imported keys. G'bye!
  try:
    woarch = line.rsplit('.', 1)[0] # Bye, arch!
    worel = woarch.rsplit('-', 1)[0] # Bye, release!
    wover = worel.rsplit('-', 1)[0] # Bye, version!
  except Exception as e: # Well nuts...
    print ('%s ** %s') % (e, line)
    continue
  print (wover)

Just redirect last year's crap into it and you'll get just the names that matter.

0
20

You can use rpm's --qf queryformat parameter. You give it a format string where you can have tags surrounded by %{}. You can see all the allowed tags with rpm --querytags

I'm guessing you'd want something like:

rpm -qa --qf "%{NAME}\n"
5
  • This will not help me as I point out at the end of the question.
    – hlovdal
    Dec 17, 2010 at 23:58
  • 1
    If you are the one to dock the answers (myself and another) it's sort of impolite to downvote based on a spec that we didn't see (not sure if it was added after i answered). This is a simple sed request then. something like sed 's/-[0-9].*\.(x86|x86_64)$//' would serve as a starting point. Dec 18, 2010 at 0:24
  • The note about formatting the output from rpm was there from the very start (I only added "with --queryformat" later), you can view the history to check, superuser.com/posts/223248/revisions
    – hlovdal
    Dec 18, 2010 at 1:29
  • Maybe it is impolite to downvote, but for a "please do not answer X" question I think it is proper policy to downvote (pure) X answers (also consider that I might find it sort of impolite to answer the with the exact thing I said I did not want).
    – hlovdal
    Dec 18, 2010 at 1:30
  • The regex will not be that simple (and I think regex is the wrong tool for this). I am currently using 's/-[0-9]\+(\.[0-9_a-z]\+)*-[0-9]\+(\.[0-9a-z])*.[^.]\+.[0-9]\+.[^.]\+$//', but there are many lines this RE fails to match and update.
    – hlovdal
    Dec 18, 2010 at 1:30
6

This is far from perfect, but it's worth a try.

$ rpm -qa --qf "%{NAME}\n" > currentlist
$ join -t . -v 1 oldlist currentlist    # show packages in oldlist not in currentlist
$ join -t . -v 2 oldlist currentlist    # show packages in currentlist not in oldlist

This sed command works on all the ones except for the group you labeled "diverse":

sed 's/-[^-]*-[^-]*\.[^.]*\.[^.]*$//'

I believe it works similarly to Ignacio's Python script.

3
  • Although not explicit stated in the answer, the oldlist file is created with the given sed command.
    – hlovdal
    Dec 18, 2010 at 12:48
  • Thank you. Although not perfect as you say (I see that it is a tiny bit too happy to remove parts so for instance fedora-package-config-smart ends up as just fedora-package-config), it works way better than the sed regex I came up with, and together with Ignacio Vazquez-Abrams' answer I can compare and merge (using kdiff3).
    – hlovdal
    Dec 18, 2010 at 12:49
  • @hlovdal: Actually, I intended for the oldlist to be as originally created, without being further processed. Dec 18, 2010 at 14:51
1

rpm is a very flexible command with a bunch of useful options.

For instance, you may want to show the date of the installation of each package using:

rpm -qa --queryformat '%{NAME}  %{INSTALLTIME:date}\n'

(--qf is the short form of --queryformat)

Have a look at:
http://www.rpm.org/max-rpm/s1-rpm-query-parts.html

1
  • This will not help me as I point out at the end of the question.
    – hlovdal
    Dec 17, 2010 at 23:58
0

Not sure why you think --queryformat won't help you... why not do as one of the previous answers suggests and use it to split out the version and architecture from the name? That way, you can output the rpm -qa listing in CSV or tab-separated format for later processing.

1
  • The point is that I already have some existing files made with rpm -qa a long time ago, and without a time machine I cannot go back and recreate those files with --queryformat. That is why.
    – hlovdal
    Dec 18, 2010 at 0:22
0

I like the above which is perfect and by far the simplest but I wish to get a list and install them on another machine so I do this:

rpm -qa --qf "%{NAME} " >installed-rpms.txt

then I do this on the next machine:

yum -y install $(cat installed-rpms.txt)

I have to add -y because I really want to do this a lot and I am sure the rpm list is what I want.

0

So long as there are no additional dashes within the version part and the release.arch part (which is the case for all the examples you list and all packages on my CentOS 7 system), this should work:

cat old-rpm-qa-list.txt | rev | cut -d- -f3- | rev

Effectively I'm just splitting the string on the dashes and throwing away the last and second to last tokens. The way it operates is by reversing the string, splitting on dash as the delimiter, keeping only the third and beyond tokens which are the name part, and then reversing that back to normal ordering.

The only special case I'm aware of that you might want to handle separately are the gpg-pubkey entries, but usually I want to just filter those out anyhow with a grep -v gpg-pubkey since they aren't installable.

To test for yourself on your own system:

rpm -qa --queryformat '%{NAME}\n' | sort > truth.txt
rpm -qa | rev | cut -d- -f3- | rev | sort > output.txt
diff truth.txt output.txt

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .