I'm trying to use for
in the shell to iterate over filenames with spaces. I read in a stackoverflow question that IFS=$'\n'
could be used and that seems to work fine. I then read in a comment to one of the answers that to make it posix compatible for shells other than bash one could use IFS=$(echo -e '\n')
.
The former works but the latter doesn't. The comment is upvoted several times. I checked the output and the variable doesn't seem to contain the newline.
#!/bin/sh
IFS=$(echo -e '\n')
echo -n "$IFS" | od -t x1
for file in `printf 'one\ntwo two\nthree'`; do
echo "Found $file"
done
echo
IFS=$'\n'
echo -n "$IFS" | od -t x1
for file in `printf 'one\ntwo two\nthree'`; do
echo "Found $file"
done
The output shows the field separator is missing for the first:
0000000
Found one
two two
three
But is proper on the second:
0000000 0a
0000001
Found one
Found two two
Found three
I found an answered question which may or may not be a duplicate of my question:
linux - When setting IFS to split on newlines, why is it necessary to include a backspace? - Stack Overflow
Is there any danger to doing what's discussed there, IFS=$(echo -en '\n\b')
? Because that adds a \b
to IFS (I checked). Can a \b
occur in a file name? I don't want my code to split a file name by mistake.
Also do you have any recommendations on how to properly handle restoration of IFS after the for
loop? Should I store it in a temporary variable, or run IFS and the for statement in a subshell? (and how to do that?) Thanks