Discussion:
[Help-bash] Is there a way to allow `read` get empty field with IFS=$'\t'?
Peng Yu
2018-03-07 21:52:49 UTC
Permalink
Hi,

When IFS=$'\t', `read` will not get empty fields like the one between
'a' and 'b c' below. Is there a way to allow it do so? Thanks.

IFS=$'\t' read -r -a a <<< $'a\t\tb c\td'
declare -p a
declare -a a=([0]="a" [1]="b c" [2]="d")
--
Regards,
Peng
Greg Wooledge
2018-03-07 21:58:52 UTC
Permalink
Post by Peng Yu
Hi,
When IFS=$'\t', `read` will not get empty fields like the one between
'a' and 'b c' below. Is there a way to allow it do so? Thanks.
IFS=$'\t' read -r -a a <<< $'a\t\tb c\td'
declare -p a
declare -a a=([0]="a" [1]="b c" [2]="d")
Convert your tab separators into something that is not IFS whitespace.
Then use that (whatever you chose) as IFS.

Or don't use bash.
Grisha Levit
2018-03-09 05:47:07 UTC
Permalink
Post by Peng Yu
When IFS=$'\t', `read` will not get empty fields like the one between
'a' and 'b c' below. Is there a way to allow it do so? Thanks.
You can use mapfile with -d like

$ mapfile -t -d $'\t' a < <(printf 'a\t\tb c\td')
$ declare -p a
declare -a a=([0]="a" [1]="" [2]="b c" [3]="d")
Peng Yu
2018-03-10 03:23:57 UTC
Permalink
Post by Grisha Levit
Post by Peng Yu
When IFS=$'\t', `read` will not get empty fields like the one between
'a' and 'b c' below. Is there a way to allow it do so? Thanks.
You can use mapfile with -d like
$ mapfile -t -d $'\t' a < <(printf 'a\t\tb c\td')
$ declare -p a
declare -a a=([0]="a" [1]="" [2]="b c" [3]="d")
--
Regards,
Peng
Peng Yu
2018-03-10 03:25:28 UTC
Permalink
Post by Grisha Levit
$ mapfile -t -d $'\t' a < <(printf 'a\t\tb c\td')
$ declare -p a
declare -a a=([0]="a" [1]="" [2]="b c" [3]="d")
The trailing newline is not removed but read -a does. Is there a way
to remove the trailing newline with readarray?

$ readarray -t -d $'\t' array <<< $'a\t\tb\tc'
$ declare -p array
declare -a array=([0]="a" [1]="" [2]="b" [3]=$'c\n')
--
Regards,
Peng
Grisha Levit
2018-03-10 03:41:07 UTC
Permalink
Post by Peng Yu
The trailing newline is not removed but read -a does. Is there a way
to remove the trailing newline with readarray?
$ readarray -t -d $'\t' array <<< $'a\t\tb\tc'
$ declare -p array
declare -a array=([0]="a" [1]="" [2]="b" [3]=$'c\n')
Yup, that's exactly why I suggested the process substitution method instead
of here strings.
Dennis Williamson
2018-03-10 03:55:43 UTC
Permalink
Post by Grisha Levit
Post by Peng Yu
The trailing newline is not removed but read -a does. Is there a way
to remove the trailing newline with readarray?
$ readarray -t -d $'\t' array <<< $'a\t\tb\tc'
$ declare -p array
declare -a array=([0]="a" [1]="" [2]="b" [3]=$'c\n')
Yup, that's exactly why I suggested the process substitution method instead
of here strings.
It's important to note that in order to include a final empty field, there
must be two tabs at the end of the string. If there is only one, the same
as if there were none, the array will not include a final empty element.
Daniel Mills
2018-03-12 18:15:45 UTC
Permalink
On Fri, Mar 9, 2018 at 10:55 PM, Dennis Williamson <
Post by Dennis Williamson
It's important to note that in order to include a final empty field, there
must be two tabs at the end of the string. If there is only one, the same
as if there were none, the array will not include a final empty element.
This can be solved in the general case by simply sticking an extra tab at
the end of the input string

Loading...