Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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}...
share|improve this question

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
share|improve this answer

You could set your PROJECT var to ~/admin/packages/*[^tsa]_1.txt

PROJECT="~/admin/packages/*[^tsa]_1.txt"

If you can modify it.

share|improve this answer

Use a case statement to weed out the exceptions, like this:

for f in ${PROJECT}; do
    case "$f" in *[tsa]_1*) continue;; esac

    # ... actual work here ...
done
share|improve this answer

(in bash) The exact answer to your request is to use GLOBIGNORE:

By executing this command:

LESS=+/'^ *GLOBIGNORE' man bash

read:

GLOBIGNORE
A colon-separated list of patterns defining the set of filenames to be ignored by pathname expansion. If a filename matched by a pathname expansion pattern also matches one of the patterns in GLOBIGNORE, it is removed from the list of matches.

So, by setting GLOBIGNORE like this:

$  ls *
A_1.txt  A_t_1.txt  A_ts_1.txt  A_tsa_1.txt
$ GLOBIGNORE=*t_1.txt:*s_1.txt:*a_1.txt
$ ls *
A_1.txt

After that you may restore GLOBIGNORE to empty with unset GLOBIGNORE.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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