Trying to run a basic for loop

OS : RHEL 6.1
Shell : Bash

I had a similair post on this a few weeks back. But I didn't explain my requirements clearly then. Hence starting a new thread now.

I have lots of files in /tmp/stage directory as show below.

I want to loop through each files to run a command on each file.
I want to skip those files whose names end with a number. How can I do this ? My following attempts in writing the for loop has failed.

# touch sharp
# touch sharper
# touch sharpest
# touch sharpener
# touch sharpy
# touch sharper2
# touch sharpest4

# pwd
/tmp/stage
# ls -ld *
-rw-r--r--. 1 root root 0 Oct  8 03:12 sharp
-rw-r--r--. 1 root root 0 Oct  8 03:12 sharpener
-rw-r--r--. 1 root root 0 Oct  8 03:12 sharper
-rw-r--r--. 1 root root 0 Oct  8 03:14 sharper2
-rw-r--r--. 1 root root 0 Oct  8 03:12 sharpest
-rw-r--r--. 1 root root 0 Oct  8 03:14 sharpest4
-rw-r--r--. 1 root root 0 Oct  8 03:12 sharpy
#

# for i in /tmp/stage/sharp[a-b]* ; do echo $i ; done
/tmp/stage/sharp[a-b]*
#
#
#
# for i in /tmp/stage/sharp[a-b] ; do echo $i ; done
/tmp/stage/sharp[a-b]
#
#
# for i in /tmp/stage/sharp*[a-b] ; do echo $i ; done
/tmp/stage/sharp*[a-b]
#

I want this for loop to run a command on each file like

for f in /tmp/stage/sharp[a-z]
do
 echo "Processing $f"
 # do something on $f
done

What gives the following command?

for i in sharp!(*[0-9])
do echo $i
done

Note that this is Shell expression, not REGEX ! ...

1 Like
$ ls
f1  f2  f3  fa  fb  fc

$ for f in *[!0-9]; do echo $f; done
fa
fb
fc

Regards,
Alister

1 Like

You were quite close (but allowing only a and b chars, not the entire alphabet):

for f in /tmp/stage/sharp*[a-z]
 do  echo "Processing $f"
# do something on $f
 done
1 Like

At the risk of being pedantic, I will point out that the set of files not ending in a digit and the set of files ending with a letter may not be identical. Which is the correct set is left for the OP to decide.

Regards,
Alister

1 Like

Absolutely right. I just wanted to point out that he/she stopped his/her experiments close to (somewhat discussible, yes) success.

1 Like

Thank you very much Rudic, Alister. Yes. I mistakenly entered a-b instead a-z. It has been a long day :slight_smile:

Thank you ctsgnb . I encountered the following error for the solution you've provided.

$ for i in /tmp/stage/sharp!(*[0-9]); do echo $i ; done
-bash: !: event not found

@kraljic

I tested it on my Ubuntu VM (it was working) here is what i got :

$ echo $0
/bin/bash
$ ls conv*
conv  conv2  conv2v  conv3  convvv  convvvvv4
$ ls conv!(*[0-9])
conv  conv2v  convvv
$ ls conv*[!0-9]
conv2v  convvv
$ ls conv*([!0-9])
conv  convvv
$ ls conv*(*[!0-9])
conv  conv2v  convvv
$

ctsgnb's suggestion depends on shopt extglob being on. The history expansion error you're seeing means you have it off (nothing wrong with that).

Regards,
Alister

1 Like