IFS Variable

$IFS is the linux delimiter character its used in for loops. $IFS by default just hold a space character, thus the for loop will iterate over items with spaces. Each space tells it its a new item. That’s a problem with files with spaces.

I recommend remembering this (this changes the for loop delimiter/IFS variable to a newline character so you can loop over things with spaces like windows filenames, then we set the variable back)

SAVEIFS=${IFS}
IFS=$(echo -en "\n\b")
# put your for loop codes here
IFS=${SAVEIFS}

That will make it so that for loops can have newline characters as seperator/delimiters instead of spaces.

Here is a default situation where you DONT NEED TO CHANGE IFS:

for i in 1 2 3 4 5; do
echo $i
done<span style="background-color: #ffffff; font-family: Lato, sans-serif; font-size: 16.363636016845703px; line-height: 1.5;"> </span>

That is fine, it will go over 1 2 3 4 5 no problem:

for i in bob sally smith carl; do
echo "Random Name: $i"
done

that is also fine

Example below where you need to change it. First I show the problem then the solution.

The Problem to Windows File Names Problem – default IFS

# Example of the need to change IFS to newline character

# list every file with ls or *, imagine the files have spaces (just like windows files)
# ls -1 just lists files in column fashion (useful for for loops of windows files that are stored on a linux system)
ls -1
# OUTPUT:
# This random file.txt
# Another file here.doc

# This will be a problem
for i in *; do
echo "File: $i"
done

# OUTPUT WILL BE:
# File: This
# File: random
# File: file.txt
# File: Another 
# File: file
# File: here.doc

# This happens because by default IFS is set to a space so a for loop will delimit(separate) entries by the space character

The Solution to Windows File Names Problem – changing IFS

# To fix that just set the IFS to a newline character using the weird echo syntax (which basically tells it to print exactly one new line character into the IFS variable, thus setting the IFS delimiter to a new line character, so now for loops will think new entries begin with a space)

# first we remember the old IFS setting so we can change back to it (its always good to go back to system defaults on certain parts, especially for IFS most things in bash scripts are programmed in such a way that IFS is set to a space as its default value, so permanently changing IFS to a newline character is bad practice, thus we save the value so we can change to it)

SAVEIFS=${IFS}
# set IFS to a newline cahracter
IFS=$(echo -en "\n\b")

# do our old foor loop
for i in *; do
echo $i
done

# return back to old value for the IFS value
IFS=${SAVEIFS}

Now the output should be:

# OUTPUT WILL BE:
# File: This random file.txt
# File: Another file here.doc

# That looks correct

# so all together:

SAVEIFS=${IFS}
IFS=$(echo -en "\n\b")
for i in *; do
echo $i
done
IFS=${SAVEIFS}

Note: IFS doesnt just affect for loops, they also arent just used with space characters or newline characters. Sometimes you can use them for other things, check this article out: http://bash.cyberciti.biz/guide/$IFS

Leave a Reply

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