Filenames with spaces breaking for loop, find command

Using for with find is the wrong approach here, see for example this writeup about the can of worms you are opening.

The recommended approach is to use find, while and read as described here. Below is an example that should work for you:

find . -type f -name '*.*' -print0 | 
while IFS= read -r -d '' file; do
    printf '%s\n' "$file"
done

This way you delimit the filenames with null (\0) characters, this means that variation in space and other special characters will not cause problems.

In order to update an archive with the files that find locates, you can pass its output directly to tar:

find . -type f -name '*.*' -printf '%p\0' | 
tar --null -uf archive.tar -T -

Note that you do not have to differentiate between if the archive exists or not, tar will handle it sensibly. Also note the use of -printf here to avoid including the ./ bit in the archive.


Try quoting the for loop like this:

for FILE in "`find . -type f  -name '*.*'`"   # note the quotation marks

Without quotes, bash doesn't handle spaces and newlines (\n) well at all...

Also try setting

IFS=$'\n'

This works and is simpler:

find . -name '<pattern>' | while read LINE; do echo "$LINE" ; done

Credit to Rupa (https://github.com/rupa/z) for this answer.

Tags:

Bash

Find

Scripts