33

I'm on system running a (fairly recent-)Debian-based distribution.

I'd like to generate a plain list of all installed packages matching a certain pattern. I can do that by, running, say,

apt list --installed "linux-image-*" | cut -d/ -f1

but I get lines I don't care for, e.g.:

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Listing...

So maybe I'd better not use apt. I can run dpkg-query like so:

dpkg-query --showformat='${Package}\n' --show "linux-image*"

but that's not limited to installed packages. I could use

dpkg-query --list "linux-image-*" | grep "ii"

but then I'd need to do a bunch of text processing, and who can trust those spaces, right?

So, bottom line: What's the right way to get the list of installed packages matching a pattern?


Note:

  • Bonus points if it can be a proper regexp rather than just a shell glob.
  • Having to parse the text seems like a less-than-ideal solution; if that's what you suggest, please argue why there isn't a better way.
einpoklum
  • 8,772
  • 19
  • 65
  • 129

4 Answers4

23
$ apt list --installed "linux-image-*" 2>/dev/null |awk -F'/' 'NR>1{print $1}'
linux-image-3.16.0-4-amd64
linux-image-4.11.0-1-amd64
linux-image-4.12.0-1-amd64
linux-image-4.13.0-1-amd64
linux-image-4.8.0-2-amd64
linux-image-4.9.0-1-amd64
linux-image-4.9.0-2-amd64
linux-image-4.9.0-3-amd64

Talking about regex:

$ apt list --installed "linux-image-*" 2>/dev/null |awk -F'/' 'NR>1 && $0~/4.1/{print $1}'
linux-image-4.11.0-1-amd64
linux-image-4.12.0-1-amd64
linux-image-4.13.0-1-amd64

You can also use dpkg-query with -f (--showformat) option,which when invoked without any package name, by default only installed packages are listed.

$ dpkg-query -f '${Package}\n' -W |grep 'linux-image' #-W == --show
George Vasiliou
  • 7,803
  • 3
  • 18
  • 42
  • "add `|awk -F'/' 'NR>1{print $1}'` to apt list command" is possible shortest answer for "apt list only names" – quant2016 Feb 02 '21 at 10:18
13

aptitude supports searching among all packages known to the package management tools, installed or otherwise, using regular expressions, without extraneous output, and can be told how to format its output:

aptitude search "linux-image-.*"

To list only installed packages:

aptitude search "linux-image-.* ~i"

To list only installed package names matching the regular expression:

aptitude search "linux-image-.* ~i" -F "%p"

The documentation covers the available search patterns and output format specifiers in detail. You’ll also find examples on this site, for example is there a way to use regexp with aptitude?, regexp with aptitude part 2, and Linux - display or upgrade security updates only using apt.

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
11

Here's one good way to do get the list of installed packages on a Debian-based system:

dpkg -l | grep ^ii | awk '{print $2}'

The output lines of dpkg -l can be trusted to be sane. The pattern ^ii will match the lines of installed packages, and the simple Awk will extract the second column, the package names (the same names used in apt-get install commands). Package names cannot contain whitespace, so this again is a safe operation.

janos
  • 11,171
  • 3
  • 35
  • 53
  • This works when you want to grep by version. The answers with `aptitude search` and `apt list` in this case don't. – Hi-Angel May 15 '20 at 12:19
2

In order to "trap" the searched term when grep ping dpkg output, need to encase the search term as follows. "git" is used as the specimen search term:

dpkg -l |grep "^ii  git[[:space:]]"

The carat (^) ii followed by (2) spaces prepending the searched term ensures nothing BEFORE it other than that combination of characters can match.

The [[:space:]] abutting the searched term precludes partial matches from occurring by only matching spaces immediately AFTER it.

F1Linux
  • 2,286
  • 1
  • 16
  • 28