3

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

1 Answer 1

6

The 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.

9
  • (@stephane-chazelas, thanks for the edit) And using pipe?
    – Erwann
    Feb 24, 2022 at 16:34
  • @Erwann, not sure what you mean, but which delimiter you use doesn't matter. 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
  • @StéphaneChazelas I mean swapping the order of readarray and printf, with a pipe connecting the two.
    – Erwann
    Feb 24, 2022 at 16:39
  • 1
    @Erwann, 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
  • @terdon, sorry I didn't originally intend to make such an extensive edit. I hope you don't mind. Feb 24, 2022 at 16:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .