Ibrahim Quraish
Ibrahim Quraish

Reputation: 4099

Unix read command with option -d and IFS variable combination

Looking forward to understand the behavior of read -d when it comes along with IFS variable

$ cat f1
a:b:c
d:e:f

$ while IFS= read -d: ; do echo $REPLY; done < f1
a
b
c d
e

$ while IFS=: read; do echo $REPLY; done < f1
a:b:c
d:e:f

Upvotes: 3

Views: 8534

Answers (2)

Igor Chubin
Igor Chubin

Reputation: 64623

IFS is inter field separator. You say to shell which symbols is used to split fields. It is used in two directions, not only when reading.

One special case that you use here is IFS=. You use IFS= here to correctly handle input starting with spaces.

You can compare:

echo "  a" | IFS= read a
echo "  a" | read a

That is important when you handle files and they can contain leading spaces in their names.

Please compare:

$ echo "  a" | ( IFS= read a; echo .$a. )
. a.
$ echo "  a" | ( read a; echo .$a. )
.a.

UPDATE. As you probably already noted, this construction

$ echo a | read a

doesn't work. Because shell creates a subshell for the '''read''', and you can see the value of $a only inside it.

You can also use while, what is more often:

$ echo a | while read a; do echo $a; done

Upvotes: 1

C. K. Young
C. K. Young

Reputation: 223213

IFS is used when you're reading several variables with read:

$ echo foo:bar:baz | (IFS=: read FOO BAR BAZ; echo $FOO; echo $BAR; echo $BAZ)
foo
bar
baz

Whereas, the -d option specifies what your line separator for read is; read won't read beyond a single line:

$ echo foo:bar:baz%baz:qux:quux% | while IFS=: read -d% FOO BAR BAZ; do echo ---; echo $FOO; echo $BAR; echo $BAZ; done
---
foo
bar
baz
---
baz
qux
quux

Upvotes: 7

Related Questions