When using a for File in $(find command) statement any file name with space becomes problematic. Where the space resides becomes individual arguments to the for loop. Alternately, the find in the for File in "$(find command)" quoted will only produce one large argument of all files.
The bash shell uses the (IFS) Internal Field Separator for word splitting after expansion and to split lines into words with the read builtin command. The default value is ``<space><tab><new-line>''. So, any file name with a space(s) will be split in to multiple word(s). Changing the IFS to a new-line only will remedy the situation. Please observe the following code and run time output.
Be careful modifying the IFS variable, because other utilities or commands may rely on the default IFS value. Always return the IFS variable back to the default value after your for loop code.
The bash shell uses the (IFS) Internal Field Separator for word splitting after expansion and to split lines into words with the read builtin command. The default value is ``<space><tab><new-line>''. So, any file name with a space(s) will be split in to multiple word(s). Changing the IFS to a new-line only will remedy the situation. Please observe the following code and run time output.
Code:
$ cat files_space_find
# Change the IFS variable then source this script.
function Find_files()
{
for File in $(find * -prune -type f -print)
do
echo ":${File}:"
done
}
# main
Find_files
#
### End of script
Notice, the script output uses a colon at both ends of the file name output to help discern the file name before and after spaces.
$ ls -1b
space_before between_after
files_space_find
$ ls | od -c
0000000 s p a c e _ b e f o r e b e
0000020 t w e e n _ a f t e r \n f i l
0000040 e s _ s p a c e _ f i n d \n
0000056
With the default IFS variable notice how the file name at the space location is split in to words during the for loop execution.
$ echo "$IFS" | od -c
0000000 \t \n \n
0000004
$ . files_space_find
:space_before:
:between_after:
:files_space_find:
With the IFS variable only containing a new-line the file name with spaces will no longer be split in to words.
$ IFS='
> '
$ echo "$IFS" | od -c
0000000 \n \n
0000002
$ . ./files_space_find
: space_before between_after :
:files_space_find:
$ IFS="$IFS_Saved"
$ echo "$IFS" | od -c
0000000 \t \n \n
0000004
$
Be careful modifying the IFS variable, because other utilities or commands may rely on the default IFS value. Always return the IFS variable back to the default value after your for loop code.
