TL, DR:
array_of_lines=("${(@f)$(my_command)}")
First mistake (→ Q2): IFS='\n'
sets IFS
to the two characters \
and n
. To set IFS
to a newline, use IFS=$'\n'
.
Second mistake: to set a variable to an array value, you need parentheses around the elements: array_of_lines=(foo bar)
.
This would work, except that it strips empty lines, because consecutive whitespace counts as a single separator:
IFS=$'\n' array_of_lines=($(my_command))
You can retain the empty lines except at the very end by doubling the whitespace character in IFS
:
IFS=$'\n\n' array_of_lines=($(my_command))
To keep trailing empty lines as well, you'd have to add something to the command's output, because this happens in the command substitution itself, not from parsing it.
IFS=$'\n\n' array_of_lines=($(my_command; echo .)); unset 'array_of_lines[-1]'
(assuming the output of my_command
doesn't end in a non-delimited line; also note that you lose the exit status of my_command
)
Note that all the snippets above leave IFS
with its non-default value, so they may mess up subsequent code. To keep the setting of IFS
local, put the whole thing into a function where you declare IFS
local (here also taking care of preserving the command's exit status):
collect_lines() {
local IFS=$'\n\n' ret
array_of_lines=($("$@"; ret=$?; echo .; exit $ret))
ret=$?
unset 'array_of_lines[-1]'
return $ret
}
collect_lines my_command
But I recommend not to mess with IFS
; instead, use the f
expansion flag to split on newlines (→ Q1):
array_of_lines=("${(@f)$(my_command)}")
Or to preserve trailing empty lines:
array_of_lines=("${(@f)$(my_command; echo .)}")
unset 'array_of_lines[-1]'
The value of IFS
doesn't matter there. I suspect that you used a command that splits on IFS
to print $array_of_lines
in your tests (→ Q3).
Your attempt is close to the actual solution. The relevant flag can be found in the read
help:
$ help read
...
-d delim continue until the first character of DELIM is read, rather
than newline
It doesn't explicitly mention it, but you can set the delimiter to empty, and thus it'll read until EOF.
$ IFS=, read -d '' -a myarray < myfile
$ echo ${myarray[2]}
U2FsdGVkX1/c8rTTO41zVT7gB+KL+n7KoNCgM3vfchOyuvBngdXDGjXTvXTK0jz6
Best Answer
From
man zshbuiltins
, zsh's read uses-A
instead.Hence the command is
N.B. by default, zsh array numbering begins with
1
, whereas bash's begins with0
.