Bash Shell Loop Over Set of Files
Q. How do I run shell loop over set of files stored in a current directory or specified directory?
A. You can use for loop easily over a set of shell file under bash or any other UNIX shell using wild card character.
Using a shell variable and for loop
You can use shell variable to store all file names. For example, store all *.c file in a variable called FILES:
$ FILES="*.c"
Now to loop through all files, enter:
$ for f in "$FILES"; do echo "Processing $f file.."; done
Sample shell script to loop through all files
#!/bin/bash FILES="*" for f in "$FILES" do echo "Processing $f file..." # take action on each file. $f store current file name cat $f done
Subscribe to our free e-mail newsletter or RSS feed to get all updates.
You can Email this page to a friend.
Related Other Helpful FAQs:
- Bash While Loop Example
- Delete text or paragraph between two sections using sed
- How To Find and Overcome Shell Command Line Length Limitations
- How to use bash shell
- Howto: Linux command line utilities for removing blank lines from text files
Discussion on This FAQ
Leave a Reply
We encourage your comments, and suggestions. But please stay on topic, be polite, and avoid spam. Thank you very much for stopping by our site!
Tags: BASH Shell, for command, for loop, for shell loop, loop through, set of files, shell for loop, shell script, shell variable, UNIX, unix for loop, unix shell



May 11th, 2008 at 12:35 pm
The scripts are wrong, use `$FILES` (without quotes) in the loop instead of `”$FILES”`.
May 11th, 2008 at 1:57 pm
DAY,
I don’t think so it is wrong. Do you have any problem running script?
May 11th, 2008 at 3:14 pm
Yes, the script does not work for me. Both the one directly typed in the cmd line and the one from a script file. They output of the first one is:
Processing *.c file..
The output of the second is:
Processing * file…
In fact, I just start learn the shell script. Here is another one which can do the same job:
#!/bin/sh
for f in `ls`
do
echo “Processing $f file …”
done
May 11th, 2008 at 7:36 pm
Hmm…not sure why you wouldn’t use
for file in *
or
for file in *.c
May 11th, 2008 at 8:54 pm
DAY,
Hmm, it should work (I hope you have *.c files in current directory) or try as suggested by brock.
May 12th, 2008 at 2:47 am
Thanks, vivek and Brock. Replacing “$FILES” with * or *.c works as expected. But I am just curious why the original one does not work for me. It seems that the all items following `in’ should not be enclosed in a pair of quotes, otherwise, all of them will be interpreted as one item, the string. I did try the following example, the output is as what I expected:
for f in "hello world"
do
echo "Processing $f file..."
# take action on each file. $f store current file name
done
May 12th, 2008 at 4:13 am
OK, read sth. in the bash man. page.
Quoting is used to remove the special meaning of certain characters or words to the shell. Quoting can be used to disable special treatment for special characters, to prevent reserved words from being recognized as such, and to prevent parameter expansion.
I think that’s why the original script doesn’t work. “$FILES” is treated as “*”, which does disable special treatment for the special char `*’. It’s similar when you type `echo “*”`. `echo’ would not print out everything in the `pwd`. Instead, it simply prints out `*’.
May 12th, 2008 at 5:08 pm
Actually… if $FILES + the contents of /proc/$pid/environ are together > the output of “getconf ARG_MAX” this will fail.
The proper way to do this that always works is in the “useless use of cat awards” page:
http://partmaps.org/era/unix/award.html#backticks
The for is easier to read, but it is really annoying when your scripts fail with the dreaded “argument list too long” errors.
May 12th, 2008 at 5:10 pm
Forgot to share a little bashism that makes it easy to determine a good guess of the ARG_MAX:
MAXARGS=$(( $(getconf ARG_MAX) - $(env | wc -c) ))
May 16th, 2008 at 4:46 am
I use loops like this a lot,
for x in * ; do
test -f “$x” || continue
COMMAND “$x”
done
helps to easily ignore subdirectories
June 8th, 2008 at 12:12 am
Double quotes disable the special meaning of most enclosed characters. They do not disable the interpretation of variables with a leading $. To do this yopu need single quotes.
FILES=”*” is wrong unless you want the value of $FILES to be *. The same is true of “*.c”. Lose the quotes to get what you want.
I have always just used -
for F in *
do
… etc
for F in `ls`
is OK except that
for F in ls -1 (one)
is better, but both are more cumbersome and less elegant that
for F in * (or *.c and so on)