7

Is there a way of handling invers bash v4 shell expansion, ie. treat all files NOT like a wildcard? I need to rm all files that are not of the format 'Folder-???' in this case and was wondering if there is a shorter (ie. built-in) way then doing a

for file in *
do
  [[ $i =~ \Folder-...\ ]] && rm '$i'
done

loop. (the example doesn't work, btw...)

Just out of bash learning curiosity...

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Christian
  • 1,212
  • 1
  • 15
  • 30
  • I'm afraid you can't do that and have to use regular expressions instead. – Tomas Sep 22 '11 at 15:02
  • possible duplicate of [How can I use inverse or negative wildcards when pattern matching in a unix/linux shell?](http://stackoverflow.com/questions/216995/how-can-i-use-inverse-or-negative-wildcards-when-pattern-matching-in-a-unix-linu) – Johan Oct 21 '11 at 13:22
  • 1
    @Tomas untrue; extglobs are reversible. – Charles Duffy Oct 20 '13 at 21:02

3 Answers3

18
shopt -s extglob
rm -- !(Folder-???)
Dimitre Radoulov
  • 27,252
  • 4
  • 40
  • 48
4

@Dimitre has the right answer for bash. A portable solution is to use case:

for file in *; do
  case "$file" in
    Folder-???) : ;;
    *) do stuff here ;;
  esac
done

Another bash solution is to use the pattern matching operator inside [[ ... ]] (documentation)

for file in *; do
  if [[ "$file" != Folder-??? ]]; then
    do stuff here
  fi
done
Community
  • 1
  • 1
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Hi @glenn, just to add that in both cases: `case varname ...` and _varname_ inside `[[ ... ]]` no shell word/field splitting is performed, so the identifier doesn't need to be quoted (and the quoting in this context, of course, is not harmful either). – Dimitre Radoulov Oct 19 '11 at 19:22
3

In case you are ok with find, you can invert find's predicates with -not.

As in

find -not -name 'Folder-???' -delete

(note this matches recursively among other differences to shell glob matching, but I assume you know find well enough)

Jo So
  • 25,005
  • 6
  • 42
  • 59