Last night I was trying to burn CDs. Being annoyed with k3b and choosing to use brasero instead, I went to remove k3b. I typed in:

sudo apt-get remove k3b

I hit tab twice and saw that I had both k3b and k3b-data on my system. Assuming that I wouldn't need k3b-data on my system without k3b, I wanted to remove it as well so I typed in:

sudo apt-get remove k3b*

Unfortunately I hit Y to confirm without looking. It uninstalled a whole lot more than k3b and k3b-data. It uninstalled packages which did not fit my "k3b*" regex. For example: transmission and network-manager

I'm fairly certain that I didn't have a space between k3b and * but I don't know why else it would remove all that it did. Is there something about apt-get that I'm misunderstanding?

The command you want is sudo apt-get remove '^k3b.*', because:

  • You need .* to match any character, any number of times
  • You need ^ to match the start of the string
  • You need to quote the regex to prevent bash from interpreting * as a wildcard

(This answer completes and summarizes previous info provided by qbi and Flimm)

  • 2
    This is safe and it's okay to use it but you don't need the .*. You can just use sudo apt-get remove ^k3b. The presence of ^ is sufficient to cause the argument to be interpreted as a regular expression, and when apt or apt-get interprets an argument as a regular expression, it matches it anywhere in the package name. That's why you need ^--to anchor the match to the start of the package name. The regular expression doesn't need to match the entire package name, just any part of it. – Eliah Kagan Aug 25 '17 at 10:48
  • @EliahKagan Thx for the additional info! (and indeed, it makes sense that if you need ^, then you don't need .*) – Boris Aug 25 '17 at 20:43

The regular expression * stands for zero or arbitrarily many. So you told apt-get to remove anything which contains k3 followed by any number of b, so basically everything which contains k3. If I try your command on my system it wants to remove 58 packages.

sudo apt-get remove -s k3b*
Package k3b is not installed, so not removed
Package k3b-data is not installed, so not removed
Package k3b-dbg is not installed, so not removed
Package libcanberra-gtk3-0 is not installed, so not removed
Package libcanberra-gtk3-0-dbg is not installed, so not removed
Package libcanberra-gtk3-dev is not installed, so not removed
…
The following packages will be REMOVED:
  appmenu-gtk ardour audacity brasero brasero-cdrkit firefox-globalmenu
  gconf-editor gir1.2-appindicator-0.1 gnome-applets gnome-control-center
…
0 upgraded, 2 newly installed, 58 to remove and 0 not upgraded.
  • ugh! I've been stuck working on these darn windows machines (where * just means "and anything after") for way too long! – Steve Goykovich Nov 2 '12 at 14:26
  • 14
    The * does work as a wildcard for bash like in DOS, but some commands like apt-get expect a regex. When you type sudo apt-get remove -s k3b*, bash will first look for any files in your current directory that begin with k3b. If it finds any, it will replace that argument with those filenames. If not, it will pass k3b* directly to apt-get, which will interpret it as a regex. If you don't want bash to interpret the asterisk as a wildcard first (which you probably don't), surround the argument with single quotes, like this: sudo apt-get remove -s 'k3b*' – Flimm Nov 12 '12 at 14:49
  • 3
    So the intended command would have been sudo apt-get remove -s 'k3b.*'. Just stumbled upon this answer and find it really important to know. IMHO this is quite unexpected and I would quite mark it as a "unexpected behavior" bug of apt-get... you normally expect a "glob" meaning and not a "regexp" meaning if not specified. Thanks anyway and +1! – Rmano Mar 10 '14 at 17:06
  • 1
    And for those like me who didn't know: the -s option means "simulation". It tells apt-get not to perform the operation, but simply to inform you of what would happen without the -s option. – Boris Aug 19 '14 at 18:26
  • I think that your use of single quotes to create globbing does NOT work, at least in puppet. And that is unexpected. In 'find' program, if I write find / -iname 'project*' I will find everything that begins with project, not something that has 'project' in it and anything after it. As proof regarding puppet, notice how my results say 'regex', and the results prove it? – Dennis Jun 26 '15 at 5:45

Use sudo apt-get remove ^k3b instead. When you install or remove packages, * is often dangerous and rarely needed. If you do use *, you should quote it, but that does not make it safer, because its tendency to select far more packages than you intend is the result of the way apt and apt-get interpret it and not an effect of pathname expansion.

  • Even safe uses of * are often unnecessary.
  • Unsafe uses are brutal. Removing k3b* removes every package that contains k3 anywhere in its name (and every package that depends on such a package). That's not a typo--containing k3 is sufficient, even without the b, because b* means "zero or more bs."

When you run apt or apt-get with the install, remove, or purge action, each subsequent argument is first1 interpreted as the name of an individual package. If a package with that exact name exists, the action is performed for it.

If there is no such package, apt and apt-get will check if the argument contains any of the common regular expression metacharacters2 ., ?, +, *, |, \[, ^, or $. If not, it's done--no package was found.

If it does contain any of those characters, then it is treated as a regular expression and matched against any part of any package name. It doesn't have to match the whole name. As others have said, * in a regular expression doesn't mean the same thing as * in a glob. ? doesn't either. In a regular expression:

  • * allows the previous item to appear any number of times--including just once or not at all--instead of exactly once.
  • ? makes the previous item optional--that is, it allows it to appear zero or one times.

apt-get(8) (man apt-get) says:

If no package matches the given expression and the expression contains one of '.', '?' or '*' then it is assumed to be a POSIX regular expression, and it is applied to all package names in the database. Any matches are then installed (or removed). Note that matching is done by substring so 'lo.*' matches 'how-lo' and 'lowest'. If this is undesired, anchor the regular expression with a '^' or '$' character, or create a more specific regular expression.

The manpage only mentions ., ?, and *, but it is incomplete, as +, |, [, ^, and $ are also sufficient to let apt-get or apt interpret the pattern as a regular expression.3

Although you can match any number of any characters with .*--not just *--you only need this if it would appear in the middle of your regular expression. Because the pattern is matched against any substring of a package name, it's pointless at the end (or beginning) of the pattern.

The manpage mentions ^ and $. These (especially ^) are key to writing safe, efficient patterns for use with the install, remove, or purge actions in apt or apt-get.

  • ^ anchors a regular expression to the beginning of the whole string. ^k3b selects all packages whose names start with k3b.
  • $ anchors a regular expression to the end of the whole string. k3b$ would select all packages whose names end with k3b.

Therefore you can use this command to safely remove the packages:

sudo apt-get remove ^k3b

Finally, in the specific case you mentioned, you might as well just pass both names yourself:

sudo apt-get remove k3b k3b-data

Then you avoid all this complexity! (Though anchoring with ^ is simple once you're used to it.) Or use brace expansion, which your shell expands into the above command:

sudo apt-get remove k3b{,-data}

1 There are two exceptions to this: (a) some options (e.g., -f, --purge) are recognized, and (b) some punctuation characters appearing at the end of an argument that would otherwise be taken as a package name to perform the action can be used to alter what is done (e.g., sudo apt install ubuntu-desktop^ installs the task rather than the package, and when ^ appears at the end ).

2 Other regular expression metacharacters exist. For example, \ is supported by all dialects of regular expressions and commonly used. ., ?, +, *, |, [, ^, and $ just happen to be the metacharacters the APT developers decided would trigger interpretation as a regular expression (after resolution as an exact package named has failed).

3 The easiest way to verify this is to simulate installation or removal with such a pattern, using the -s option as described above. For example, running apt -s install ^virtualbox shows that sudo apt install ^virtualbox would have the effect of attempting to install every package the package manager knows about whose name begins with virtualbox. However, this behavior can also be verified by examining the source code. Check the CacheSetHelper::PackageFromRegEx function in cacheset.cc.

You more then likely remove a lib that had k3b in it that those programs depended on.

In short you may never know. I recommend not using a wildcard to remove things and to read things when prompted (sorry).

Also with out the -n regex searches use all fields and not just names

http://ccrma.stanford.edu/planetccrma/man/man8/apt-cache.8.html

also qbi is correct your regex is flawed from the get-go

  • One other thing, In cases like yours (k3b and k3b data) just apt-get uninstall k3b. Apt will then inform you if you have things installed that you no longer need, and what you need to do to remove them. – coteyr Nov 2 '12 at 14:21
  • wow! I never would have expected it to search within descriptions too! yeah, this is definitely something I'll never do again! (and I'll be sure to read things next time :P) – Steve Goykovich Nov 2 '12 at 14:28
  • The link is broken, would you mind clarifying how to use the -n? – Seanny123 Sep 17 '13 at 8:39
  • -n means only search in the names field. – coteyr Sep 17 '13 at 13:09
  • After trying, the -n option is not recognized by apt-get remove, only by apt-get cache. It seems that actually, apt-get remove only looks for package names, not descriptions. – Boris Aug 19 '14 at 18:45

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.