I'm having a variable with multiple strings, which can contain multiple lines:
var="foo 'bar baz' 'lorem
ipsum'"
I need all of them as array elements, so my idea was to use xargs -n1
to read every quoted or unquoted string into separate array elements:
mapfile -t arr < <(xargs -n1 <<< "$(echo "$var")" )
But this causes this error:
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
Finally the only idea I had, was to replace the line feed against a carriage return and restore it afterwards:
# fill array preserve line feed (dirty)
mapfile -t arr < <(xargs -n1 <<< "$(echo "$var" | tr '\n' '\r')" )
# restore line feed
for (( i=0; i<${#arr[@]}; i++ )); do
arr[i]=$(echo "${arr[$i]}" | tr '\r' '\n')
done
It works:
# for (( i=0; i<${#arr[@]}; i++ )); do echo "index: $i, value: ${arr[$i]}"; done
index: 0, value: foo
index: 1, value: bar baz
index: 2, value: lorem
ipsum
But only as long the input variable does not contain a carriage return.
I assume I need xargs
output every result delimited by a null byte and import with mapfile
's -d ''
, but it seems xargs
is missing a print0
option (tr '\n' '\0'
would manipulate the multi-line string itself).