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).
Best Answer
Or if you do want to suppress the empty elements like in your tempvar approach:
IOW, you need to quote the command substitution. Otherwise the
s:\t:
applies on the joining (with the first character of$IFS
) of the fields resulting of the$IFS
-splitting of the command substitution.Alternatively, you could set
$IFS
to the empty string or to a single non-whitespace character.