Reputation: 4099
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
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
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