48

I have a list of packages on my system, that were installed and removed again, but not purged, i.e. there are still a lot of conffiles etc. laying around.

The output of dpkg --get-selections | grep deinstall lists about 85 different packages which I don't need and want to be purged entirely.

So my short question, which I decided to finally ask after experimenting around has lead to this problem, is:

How do I completely purge previously installed packages that are already removed?

Reinstalling and then purging is not an option, of course.

7
  • 1
    "Reinstalling and then purging is not an option, of course." LoL ;)
    – TellMeWhy
    Commented Oct 19, 2015 at 12:45
  • @DevRobot I don't see the joke. It would be possible and pretty surely work, but don't have the time to download and install tons of packages just to get rid of them...
    – Byte Commander
    Commented Oct 19, 2015 at 12:47
  • 1
    I know - it's the of course - relates :)
    – TellMeWhy
    Commented Oct 19, 2015 at 12:51
  • I think you can do sudo apt-get purge [package] after you have removed them. I just tried it and it worked.
    – Jos
    Commented Oct 19, 2015 at 12:53
  • 2
    This is not a duplicate. The referenced article solves the problem for a single package. This is about cleaning up multiple packages without manually fiddling around.
    – Andrew
    Commented Apr 11, 2018 at 0:13

5 Answers 5

61

I just found the following command which worked:

sudo apt-get purge $(dpkg -l | grep '^rc' | awk '{print $2}')
7
  • Hmm, I suspect this will hit the command line argument length limit if you have 50000 uninstalled package. waltinator's solution below does not. Not that I see that ever happening.
    – Rolf
    Commented Feb 3, 2018 at 11:40
  • dpkg -l | awk '/^rc/{print $2}' | sudo xargs apt-get purge You're welcome.
    – Tobia
    Commented Jul 18, 2019 at 22:01
  • @Tobia that last part should be sudo xargs apt -y purge, to avoid it attempting to ask for confirmation in a subshell. Commented Jan 29, 2021 at 18:03
  • 1
    Or just using dpkg: dpkg -l | awk '/^rc/ {print $2}' | sudo xargs dpkg -P Commented Jul 14, 2021 at 11:19
  • 1
    There really should be a standard command in apt for doing this. Commented Aug 10, 2021 at 5:47
29

dpkg --get-selections | grep deinstall produces a list of package names with the word "deinstall":

$ dpkg  --get-selections | grep deinstall
account-plugin-windows-live         deinstall
debarchiver                         deinstall
flashplugin-installer               deinstall
    ...

By asking awk to print only the first field we get:

$ dpkg --get-selections | awk '$2 == "deinstall" {print $1}'
account-plugin-windows-live
debarchiver
flashplugin-installer
    ...

Now that we have the list of packages, xargs will let us feed the list of packages to a command (or commands, if the list is long enough):

dpkg --get-selections | awk '$2 == "deinstall" {print $1}' | xargs sudo apt-get purge --dry-run

When you are happy with the simulated results, replace --dry-run with -y in the apt-get command.

Relevant documentation:

man dpkg awk xargs apt-get
3
  • 6
    On my system , Ubuntu 15.04, I had to add the -y option to apt-get to stop the command from aborting before the packages were removed. Commented Oct 20, 2015 at 1:24
  • For those that don't awk, you can use grep deinstall | cut -f1 instead of awk '$2 == "deinstall" {print $1}'. Using cut may actually flow better with this style write up.
    – cbarrick
    Commented Feb 15, 2019 at 17:45
  • Very nice answer. A simpler alternative would be to verify that aptitude search '~c' emits the list of packages you want to remove and then you just do sudo aptitude purge '~c' to remove all those packages. Also try aptitude search '~o' to list obsolete packages (that is, packages that are no longer supported by any repository you have). Commented Mar 4, 2019 at 10:58
4

My fifty cents, a simple oneliner:

First test with

dpkg --get-selections | awk '$2=="deinstall" {system("sudo apt-get --dry-run purge "$1)}'

and bye bye

dpkg --get-selections | awk '$2=="deinstall" {system("sudo apt-get -y purge "$1)}'

Example

% dpkg --get-selections | grep deinstall
nginx-common                    deinstall

% dpkg --get-selections | awk '$2=="deinstall" {system("sudo apt-get -y purge "$1)}'

% dpkg --get-selections | grep deinstall
[no output]
1
  • Or sudo apt-get --dry-run purge $(dpkg --get-selections | awk '$2=="deinstall" { print($1) }') to avoid spawning a new shell for every package installed. Replace --dry-run with -y once you feel comfortable about the operation. Commented Jan 11, 2023 at 8:02
3

If you just want to purge the whole list, you can use this command; it will perform a dry run, in case essential packages are going to be removed, which you probably don't want to happen:

dpkg --get-selections | sed -n 's/\tdeinstall$//p' | xargs sudo apt-get --dry-run purge

If no essential package is going to be removed, it's safe to run the actual command:

dpkg --get-selections | sed -n 's/\tdeinstall$//p' | xargs sudo apt-get --yes purge
  • sed -n 's/\tdeinstall$//p': prints only lines in stdin where a tabulation followed by a deinstall string could be removed from the end of the line; this has the effect of printing only the lines containing a tabulation followed by a deinstall string at the end of the line without the actual tabulation followed by the deinstall string at the end of the line
  • xargs sudo apt-get --yes purge: passes each line in stdin as an argument to sudo apt-get --yes purge
1

I asked this myself a couple of days ago. Came up with

apt-get purge $(dpkg -l | awk 'BEGIN{ORS=" "} /^rc/{ print $2}')

The removed but not purged packages appear in the output of dpkg -l with rc at the beginning. awk picks out the second column aka the name of the package and prints them space-separated.

1
  • 3
    Even easier: aptitude purge ?config-files
    – Rolf
    Commented Feb 7, 2019 at 23:45

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