How to clean var/cache/apt in a way that it leaves only the latest versions of each package

21,683

Solution 1

I propose the following bash script

#!/bin/bash

cd /var/cache/apt/archives/
printf '%s\n' *.deb | 
  awk -F_ '{ print $1 }' |
  sort -u | 
  while read pkg; do 
    pkg_files=($(ls -t "$pkg"_*.deb))
    nr=${#pkg_files[@]}
    if ((nr > 1)); then
      unset pkg_files[0]
      echo rm "${pkg_files[@]}"
    fi
  done

Remove the echo from the rm line if you are satisfied with the output list.

What it does?

  1. It list all deb package files
  2. remove everything in the filename from the first "_" to the end, obtaining the package name
  3. sort the names, removing duplicates
  4. for each name

    1. list the package files corresponding to that name in time order
    2. count the number of package files in the list
    3. if there is more than one package in the list

      1. remove from the list the first and newer file
      2. remove from the disk all other files corresponding to that name

It could be improved in efficiency, by listing only package files corresponding to package names obtained from the difference between sort and sort -u.

Solution 2

use the autoclean option to apt-get or aptitude

sudo apt-get autoclean
sudo aptitude autoclean

From the man page

clean

clean clears out the local repository of retrieved package files. It removes everything but the lock file from /var/cache/apt/archives/ and /var/cache/apt/archives/partial/.

autoclean

Like clean, autoclean clears out the local repository of retrieved package files. The difference is that it only removes package files that can no longer be downloaded, and are largely useless. This allows a cache to be maintained over a long period without it growing out of control.

Solution 3

It is necessary to emphasize that neither apt-get autoclean, nor aptitude autoclean delete older versions, but remove obsolete packages, which are not present in the repository anymore.

Moreover, the scripts proposed in other answers ignore packet's architecture, meaning that if you have packages with different architectures only one will be preserved and others deleted

I.e. none of the available answers provide a comprehensive solution. Thus, here is a command line as an alternative to other answers:

$ basename -a /var/cache/apt/archives/*.deb | cut -d _ -s -f 1,3 --output-delimiter=_*_ | uniq -d | xargs -I{} sh -c "find /var/cache/apt/archives/ -maxdepth 1 -name {} -print | sort -V | head -n -1" | xargs -r sudo rm

Explanation

basename -a /var/cache/apt/archives/*.deb

lists all filenames without their full path.

cut -d _ -s -f 1,3 --output-delimiter=_*_

replaces package version with asterisk (*) keeping base package name (prefix) and its architecture (suffix).

uniq -d

drops duplicate entries and simultaneously drops entries without duplicates.

xargs -I{} sh -c

for every entry executes command enclosed in quotes and substitutes {} pattern with the input file mask.

find /var/cache/apt/archives/ -maxdepth 1 -name {} -print

executes non-recursive search in the archive directory for the target pattern printing result to the standard output.

sort -V

sorts results for every search.

head -n -1

drops the last result, i.e. the one with the numerically highest version (other results will be removed in the end, but the last one will stay).

xargs -r sudo rm

puts results from all searches together and passes them to the remove command executed with super-user privilege.

Share:
21,683

Related videos on Youtube

Luis Alvarado
Author by

Luis Alvarado

System Engineer Social Engineer Master in Pedagogy Master in Open Source CCNA Certified Linux Foundation Certified Former Askubuntu Moderator Stack Careers | Linkedin | Launchpad | Ubuntu Wiki - Random SE Stuff - Latin American Members | JC Race Award | Human Robot Award 74

Updated on September 18, 2022

Comments

  • Luis Alvarado
    Luis Alvarado over 1 year

    I want to know a way to clean the var/cache/apt folder in a way that it only leaves the latest version of a package if it has several versions or it leaves a package if it is the only one of that program.

    For example I have several vlc packages (vlc_1.1.11, vlc_1.1.12..) and several wine packages (wine1.3_1.3.34,wine1.3_1.3.35,wine1.3_1.3.36,wine1.3_1.3.37...) and many others like this.

    So how to do a clean up in this folder that it leaves only the latest packages. At the moment I have 2.5GB and most of it are just older packages mixed with the newer ones.

  • Luis Alvarado
    Luis Alvarado over 12 years
    Can you add sudo aptitude autoclean. Also the autoclean in both cases (apt-get and aptitude) still leaves older versions that make a huge jump like thunderbird 8.0 and thundebird 9.0. It did however remove the thinderbird 8.x older packages but it leaves like the full release versions without taking into consideration that 9.0 is above 8.0. This is just one of many cases I still have left. Any other ideas to face this amount of older packages?
  • Panther
    Panther over 12 years
    I am sorry, if autoclean did not work I do not know of a simple method. Hope someone else has a better suggestion.
  • Luis Alvarado
    Luis Alvarado over 12 years
    It worked perfectly. I am also giving a +1 to bodhi because autoclean did also help in cleaning up a bit. So maybe both together do a great work. Thanks enzotib.
  • Jags
    Jags over 2 years
    okay, thank you
  • Jags
    Jags over 2 years
    hi @trudy I just tried the modified command but it's not even asking for password for sudo. The cursor just drops to next line/prompt. I'm not sure if I'm missing something here. The command I've tried: basename -a /var/cache/apt/archives/*.deb | cut -d _ -s -f 1,3 --output-delimiter=_*_ | uniq -d | xargs -I{} sh -c "find /var/cache/apt/archives/ -maxdepth 1 -name {} -print | sort -n | head -n -1" | xargs -r sudo rm. Thank you.
  • Trudy
    Trudy over 2 years
    @Jags, that's right. Adding -r flag to xargs prevents command execution, if inbound list of arguments is empty (see man xargs for more info) . If there is nothing to delete in your system, then sudo rm is not executed. This is the reason why you are not asked for the root password. For troubleshooting, you can remove the last pipe | xargs -r sudo rm. Then the command will simply print the list of packages for deletion. In your case it will print nothing.
  • Jags
    Jags over 2 years
    Thank you so much @trudy for the explanation, and yes at the moment there is nothing to delete.