2

How can I get the complementary results of a wildcard expansion?

If I want to list the files that have roc in their names, I run

ls *roc*

but what if I want all the files that do not have roc in the name?

ls *[!r][!o][!c]* and ls *[!roc]*

do not work. There is a simple way to do this "oppposite" expansion?

Note: I'm using bash

Kusalananda
  • 333,661
fich
  • 330

2 Answers2

3

The bash shell supports extended globbing patterns if you enable them with

shopt -s extglob

Once enabled, the pattern !(*roc*) would match any non-hidden name that does not match *roc*, i.e. any name that does not contain the string roc.

From the bash manual:

If the extglob shell option is enabled using the shopt builtin, several extended pattern matching operators are recognized. In the following description, a pattern-list is a list of one or more patterns separated by a |. Composite patterns may be formed using one or more of the following sub-patterns:

?(pattern-list) Matches zero or one occurrence of the given patterns

*(pattern-list) Matches zero or more occurrences of the given patterns

+(pattern-list) Matches one or more occurrences of the given patterns

@(pattern-list) Matches one of the given patterns

!(pattern-list) Matches anything except one of the given patterns

Kusalananda
  • 333,661
  • Much simpler that I expected. But so, I looked up, and we have also the solutions for zsh and other shells: https://unix.stackexchange.com/questions/102427/remove-all-but-one-or-more-kind-of-filetype – Giacomo Catenazzi Sep 30 '20 at 10:35
1

Note: this is not what you ask, just a workaround which delivers what you ask

Usually I reframe the problem, and so I do:

ls * | grep -v roc

I prefer using common tools (and common command that I use), instead of looking for a thing I'll use probably once a year (and so I'll probably forget).

Working with wildcard may become very complex: different shell have different results, and so it may make scripts non portable.

  • Kusalananda's answer is what I was looking for, but I liked your view too. Good reminder! – fich Sep 30 '20 at 10:14
  • Note that this may not do what you expect if you have non-hidden subdirectories in the current directory (or names containing newlines). – Kusalananda Sep 30 '20 at 10:42
  • @Kusalananda: right a ls -d | grep -v roc | xargs ls is ugly, but comparable (and it allows custom options on last ls). Still portable – Giacomo Catenazzi Sep 30 '20 at 11:22