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

5

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 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 at 16:38
  • @StéphaneChazelas I mean swapping the order of readarray and printf, with a pipe connecting the two.
    – Erwann
    Feb 24 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 at 16:44
  • @terdon, sorry I didn't originally intend to make such an extensive edit. I hope you don't mind. Feb 24 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.