3

I find myself frequently doing the following:

for f in `find -foo -bar -baz`; do
  process "$f"
done

This of course doesn't work for file names with spaces. How can I handle such cases?

AdSR
  • 2,097
  • 3
  • 15
  • 9

5 Answers5

4

Find and xargs work well together. find can print the names of the files with a \0-delimiter (option print0) and xargs can read them in that format (option -0):

find . -type f -print0 | xargs -0 echo
soulmerge
  • 73,842
  • 19
  • 118
  • 155
  • 1
    Don't forget xargs! On lists of very large numbers of files, you may find yourself getting the dreaded "Too many arguments" error. These two O'Reilly articles explain the situation: http://linuxdevcenter.com/pub/a/linux/lpt/09_21.html http://linuxdevcenter.com/pub/a/linux/lpt/09_22.html – Jim Feb 16 '10 at 21:49
2
find . -type f | while read file; do 
     process "$f"
done;
Drakosha
  • 11,925
  • 4
  • 39
  • 52
1

If you are using find already, why not simply use exec

find -foo -bar -baz -exec process '{}' \;

The alternative solution would be to change the IFS variable (inter field seperator)

amo-ej1
  • 3,279
  • 26
  • 35
1

bash 4

shopt -s globstar
for file in /path/**
do
  process "$file"
done
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
0

In such cases, my approach is to build the list before the for command and replace whitespace inside element names by another character or string which is unlikely to appear.

Then inside the loop, I replace back that specific string by a whitespace.

An example:

list=`find -foo -bar -baz | tr ' ' 'µ'`
for fx in $list ; do
    f=`echo $fx | tr 'µ' ' '`
    process "$f"
done
mouviciel
  • 66,855
  • 13
  • 106
  • 140