I was reading this Q&A: How to loop over the lines of a file?
What is the
IFS variable? And what is its usage in the context of
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.Sign up to join this community
IFS isn't directly related to looping, it's related to word splitting.
IFS indirectly determines how the output from the command is broken up into pieces that the loop iterates over.
When you have an unprotected variable substitution
$foo or command substitution
$(foo), there are two cases:
"$foo", or in a variable assignment
x=$foo, then the string resulting from the substitution is used as-is.
$IFSis considered a word separator. For example
IFS=":"; foo="12:34::78"; echo $fooprints
12 34 78(with two spaces between
78, since there's an empty word).
foo="*"; echo $fooprints the list of files in the current directory.
For loops, like many other contexts, expect a list of words. So
for x in $(foo); do …
$(foo) into words, and treats each word as a glob pattern. The default value of
IFS is space, tab and newline, so if
foo prints out two lines
hello world and
howdy then the loop body is executed with
IFS is explicitly changed to contain a newline only, then the loop is executed for
hello world and
IFS is changed to be
o, then the loop is executed for
␤ is a newline character) and
IFS stands for
Internal Field Separator - it's a character that separates fields. In the example you posted, it is set to new line character (
\n); so after you set it,
for will process text line by line. In that example, you could change the value of
IFS (to some letter that you have in your input file) and check how text will be split.
BTW, from the answer you posted the second solution is the recommended one...
As @jasonwryan noticed, it's not
Input came from
awk in which there is also
Output Field Separator.
IFS The Internal Field Separator that is used for word splitting after expansion and to split lines into words with the read builtin command. The default value is "<space><tab><newline>".
This is one of Bash's internal variables. It determines how Bash recognizes fields, or word boundaries, when it interprets character strings.
While it defaults to whitespace (space, tab, and newline), it may be changed, for example, to parse a comma-separated data file.
In addition to previous great answers, let me just add that IFS is very useful for efficient and portable parsing in simple cases in combination with set. Efficient, because avoids using of subshells and spawning tools like grep or sed:
resolutions="640x480,320x240" xIFS=$IFS IFS=',' for res in $resolutions; do xxIFS=$IFS IFS='x' set -- $res width=$1 height=$2 # handle width and height IFS=$xxIFS done; IFS=$xIFS
Just note that we need to store and recover previous value of IFS to avoid undesired breakages in other parts of script.