Ankur Agarwal
Ankur Agarwal

Reputation: 24768

IFS usage in bash

I have

$ IFS=123

$ myvar=abc1def1ghi

$ for i in "$myvar";  do echo i $i;  done
i abc def ghi

$ for i in $myvar;  do echo i $i;  done
i abc
i def
i ghi

$ myvar="abc1def1ghi"

$ for i in "$myvar";  do echo i $i;  done
i abc def ghi

$ for i in $myvar;  do echo i $i;  done
i abc
i def
i ghi

I think I understand whats happening in 2nd and 4th for loops. But I do not understand why 1 was not printed in 1st and 3rd for loops. The whole idea of IFS is confusing to me in general.

Upvotes: 2

Views: 5875

Answers (2)

Md Shihab Uddin
Md Shihab Uddin

Reputation: 561

IFS or internal field separator is a sequence of characters where each character acts as a delimiter to split a result into multiple pieces.To understand the differences of the output, we need to see when the IFS has been applied on the string. Let's see first one:

$ IFS=123
$ myvar=abc1def1ghi
$ for i in "$myvar";  do echo i $i;  done
i abc def ghi

If we put values of each variables, the piece of code will be looked like this:

$ IFS=123
$ myvar=abc1def1ghi
$ for i in "abc1def1ghi";  do echo i abc1def1ghi;  done

IFS is applied only at echo i abc1def1ghi. So the output will be i abc def ghi. Now let's see the second one:

$ IFS=123
$ myvar=abc1def1ghi
$ for i in $myvar;  do echo i $i;  done

For the above code, the IFS will be applied at the building of the for loop when the myvar value is put and the code will look like this:

$ IFS=123
$ myvar=abc1def1ghi
$ for i in abc def ghi;  do echo i $i;  done

So the for loop will iterate three times and the output will be:

   i abc
   i def
   i ghi

So the final conclusion is that due to the double-quotes on the $myvar , IFS has not been applied on that.

Upvotes: 3

Tejas Patil
Tejas Patil

Reputation: 6169

When you say $var_name then 1 is interpreted as a separator and hence you see the string as cut into pieces.

$ IFS=123

$ myvar=abc1def1ghi

$ echo $myvar
abc def ghi

When you add quotes around the variable, you demand for the absolute value of the variable without any processing.

$ echo "$myvar"
abc1def1ghi

Now coming to your question about 1st loop,

$ for i in "$myvar";  do echo i $i;  done

is equivalent to

$ for i in "abc1def1gh1";  do echo i $i;  done

'i' gets assigned "abc1def1gh1" and it prints out the value of variable 'i'. This time '1' is interpreted as a separator while printing 'i'. This is what happened while running the loop:

$ i="abc1def1gh1"

$ echo $i
abc def gh

Same thing happens in the 3rd loop.

Now if you want '1' to be printed, then add quotes around $i in the loop. ie. change this:

$ for i in "abc1def1gh1";  do echo i $i;  done
i abc def gh

to

$ for i in "abc1def1gh1";  do echo i "$i";  done
i abc1def1gh1

Upvotes: 5

Related Questions