Bash – How to use ‘*’ to capture everything with exceptions

bashwildcards

For example, I have files named

A_1.txt A_t_1.txt A_ts_1.txt A_tsa_1.txt

in a directory ~/admin/packages/.

I am building a for loop to by globbing to A_1.txt

for f in ~/admin/packages/*_1.txt

It's obvious that this can potentially glob to any one of these files.

Specifically I would like to use an "exception" command (if it exists) to say glob to any file as long as it does not have a t, s, a before _1.txt.

EDIT: I forgot to mention that I have the path stored as a variable.

PROJECT="~/admin/packages/*_1.txt"

for f in ${PROJECT}...

Best Answer

You can do this using the following extglob pattern in bash:

!(*t|*s|*a)_1.txt

Enable extglob at first (if not enabled) by:

shopt -s extglob

Then you can do:

for f in ~/admin/packages/!(*t|*s|*a)_1.txt; do ##Something; done

Example:

$ echo *_1.txt
A_1.txt Ab_1.txt A_t_1.txt A_ts_1.txt A_tsa_1.txt

$ shopt -s extglob

$ echo !(*t|*s|*a)_1.txt
A_1.txt Ab_1.txt

Shortened (thanks to chaos):

!(*[tsa])_1.txt
Related Question