Using find in a bash script

Here’s something that will hopefully save someone the frustration that I experienced getting this working. I am writing a script that needs to traverse a directory structure, then operate on the files it finds (read DICOM tags, modify/add tags). The reading and modifying was simple enough, but I could not get find to work inside the script, so basically resorted to running a command like:

$ find . -type f -exec fileops.sh {} \;

That worked fine, but I really wanted to have it all integrated into a single command. The problem I had was that the output of a find command couldn’t be used to iterate in a for loop – as a scalar (FILES=`find . -type f`) it was a single string, and as an array (FILES=(`find . -type f`)) elements would be split on spaces and newlines, which breaks if your paths have spaces in them.

The trick here is to change the IFS variable, which tells bash what to split strings on (by default it is space, tab or newline).  In my case, the output of find is separated by newline characters. Change it to a newline and now it works as expected. yay! Here’s the code:

#!/bin/bash
# IFS controls how bash splits strings (by default, whitespace.
# change to newline
OLD_IFS=${IFS}
IFS=$'\n'
# dummy function for demo
fileops () {
    echo $1
}
FILES=(`find "$1" -type f`)
    for i in "${FILES[@]}" ; do
fileops "$i"
done
# restore IFS
IFS=${OLD_IFS}

Leave a Reply

Your email address will not be published. Required fields are marked *