About Linux FAQ

Browse More FAQs:

Bash Shell Loop Over Set of Files

Posted by Vivek Gite [Last updated: May 11, 2008]

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:

Discussion on This FAQ

  1. DAY Says:

    The scripts are wrong, use `$FILES` (without quotes) in the loop instead of `”$FILES”`.

  2. vivek Says:

    DAY,

    I don’t think so it is wrong. Do you have any problem running script?

  3. DAY Says:

    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

  4. Brock Noland Says:

    Hmm…not sure why you wouldn’t use

    for file in *

    or

    for file in *.c

  5. vivek Says:

    DAY,

    Hmm, it should work (I hope you have *.c files in current directory) or try as suggested by brock.

  6. DAY Says:

    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

  7. DAY Says:

    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 `*’.

  8. Jeff Schroeder Says:

    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.

  9. Jeff Schroeder Says:

    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) ))

  10. David Thompson Says:

    I use loops like this a lot,

    for x in * ; do
    test -f “$x” || continue
    COMMAND “$x”
    done

    helps to easily ignore subdirectories

  11. Baz Says:

    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)

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!

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word

Tags: , , , , , , , , , , ,

Copyright © 2006-2008 nixCraft. All rights reserved - TOS/Disclaimer - Privacy policy - Sitemap - Powered by Open source software.