16

I am trying to exclude a certain string from a file search.

Suppose I have a list of files: file_Michael.txt, file_Thomas.txt, file_Anne.txt.

I want to be able and write something like

ls *<and not Thomas>.txt

to give me file_Michael.txt and file_Anne.txt, but not file_Thomas.txt.

The reverse is easy:

ls *Thomas.txt

Doing it with a single character is also easy:

ls *[^s].txt

But how to do it with a string?

Sebastian

skaffman
  • 398,947
  • 96
  • 818
  • 769
steigers
  • 201
  • 2
  • 3
  • 6
  • 1
    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) – Hasturkun Oct 23 '11 at 10:47

3 Answers3

19

You can use find to do this:

$ find . -name '*.txt' -a ! -name '*Thomas.txt'
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
17

With Bash

shopt -s extglob
ls !(*Thomas).txt

where the first line means "set extended globbing", see the manual for more information.

Some other ways could be:

find . -type f \( -iname "*.txt" -a -not -iname "*thomas*" \)

ls *txt |grep -vi "thomas"
beaver
  • 523
  • 1
  • 9
  • 20
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
2

If you are looping a wildcard, just skip the rest of the iteration if there is something you want to exclude.

for file in *.txt; do
    case $file in *Thomas*) continue;; esac
    : ... do stuff with "$file"
done
tripleee
  • 175,061
  • 34
  • 275
  • 318