Obviously I'm not doing it right, but I think the intended outcome is clear (${#arr[@]}
=3)
$ readarray -d "\t" arr < <(printf "%s\t%s\t%s" "x" "y" "z"); echo "${#arr[@]}"
> 1
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 communityThe shell doesn't know that \t
should be a tab. It is looking for a literal \
followed by a t
(ignoring the latter as delimiters can only be single bytes (not even characters)):
$ readarray -d "\t" arr < <(printf %s 'x\ty\tz'); echo "${#arr[@]}"
3
$ typeset -p arr
declare -a arr=([0]="x\\" [1]="ty\\" [2]="tz")
For actual tabs, you need to escape like this:
$ readarray -d $'\t' arr < <(printf "%s\t%s\t%s" "x" "y" "z"); echo "${#arr[@]}"
3
Note that your third value above is not delimited. It's fine here because it's not empty, but had it been empty, you'd have gotten:
$ readarray -d $'\t' arr < <(printf "%s\t%s\t%s" "x" "y" ""); echo "${#arr[@]}"
2
To allow any value (that doesn't contain TAB nor NUL characters) including empty ones, you'd want to make sure they are delimited with:
printf '%s\t' "$val1" "$val2" "$val3"
Same as:
printf '%s\t%s\t%s\t' "$val1" "$val2" "$val3"
You may also want to remove the delimiters from the array elements with readarray
's -t
option.
readarray -d x
is to process delimited values. It's typically used with newline or NUL delimiters to read lines or NUL-delimited records (like the output of find -print0
) into an array.
Feb 24, 2022 at 16:38
readarray
and printf
, with a pipe connecting the two.
printf | readarray
would be the natural way to do it, but because by default bash runs pipeline components in subshells, readarray < <(printf)
is the common work-around for that. In any case, even with shopt -s lastpipe
which causes the rightmost pipeline component not to run in a subshell (for non-interactive shells only), that won't make a functional difference.
Feb 24, 2022 at 16:44