HOWTO Loop over multiple files using Bash

HOWTO Loop over multiple files using Bash

From Consultancy.EdVoncken.NET

Jump to: navigation, search

Contents

Problem

You wish to loop over multiple files, but there may be no files to process.

Solution

Use the following construct:

 shopt -s nullglob
 cd /tmp
 for file in *.ext;
 do
   echo "Processing $file"
 done

This will process each file in turn. If no files match the specification, the for-loop is not executed.

Discussion

The "shopt -s nullglob" is essential here. Without the "nullglob" shell option, the script will simply return the literal string (file="*.ext") if there are no files matching the pattern.

This is obviously not what we want. By setting the "nullglob" shell option, the expression will return an empty string if there are no files matching the glob pattern.

It is tempting to invoke another program (/bin/ls):

 cd /tmp
 for file in `/bin/ls -1 *.ext 2>/dev/null`;
 do
   echo "Processing $file"
 done

This solution has problems with filenames containing whitespace, and should be avoided.

Alternatives

As noted by <a href="http://vanzantvoort.org/">John van Zantvoort</a>: with GNU xargs, there is an additional "-r" / "--no-run-if-empty" option switch that handles empty result sets:

 find $PWD -mindepth 1 -maxdepth 1 \(  -iname '*.zip' -o -iname '*.gz' \) -print0 | xargs -0 -r ls -ld

Explanation: find all items with .zip or .gz extensions in the current directory, and run "ls -ld" on them if there are any results. The use of "find $PWD" instead of "find ." ensures that full paths are displayed:

 $   find $PWD -mindepth 1 -maxdepth 1 \(  -iname '*.zip' -o -iname '*.gz' \) -print0 | xargs -0 ls -ld
 -rw-r--r--@ 1 ed  staff    418571 Mar 10 17:33 /Users/ed/Downloads/RecBoot-1.0.2.zip
 -rw-r--r--@ 1 ed  staff   8708296 Apr  4 11:55 /Users/ed/Downloads/colloquy-latest.zip
 -rw-r--r--@ 1 ed  staff  40834183 Apr  2 23:47 /Users/ed/Downloads/eagle-mac-5.11.0.zip
 
 $   find . -mindepth 1 -maxdepth 1 \(  -iname '*.zip' -o -iname '*.gz' \) -print0 | xargs -0 ls -ld
 -rw-r--r--@ 1 ed  staff    418571 Mar 10 17:33 ./RecBoot-1.0.2.zip
 -rw-r--r--@ 1 ed  staff   8708296 Apr  4 11:55 ./colloquy-latest.zip
 -rw-r--r--@ 1 ed  staff  40834183 Apr  2 23:47 ./eagle-mac-5.11.0.zip