如何使用多行命令输出填充bash数组?
例如,给出了这个printf命令:
$ printf 'a\nb\n\nc\n\nd\ne\nf\n\n'
a
b
c
d
e
f
我想填充一个bash数组,好像我写的那样:
$ arr[0]='a
b'
$ arr[1]='c'
$ arr[2]='d
e
f'
因此可以循环播放:
$ for i in "${arr[@]}"; do printf "<%s>\n" "$i"; done
<a
b>
<c>
<d
e
f>
我尝试过使用NUL字符来分隔我想要的数组字段而不是空行的各种形式,因为这似乎是我最好的选择,但到目前为止没有运气,例如:
$ IFS=$'\0' declare -a arr="( $(printf 'a\nb\n\0c\n\0d\ne\nf\n\0') )"
$ for i in "${arr[@]}"; do printf "<%s>\n" "$i"; done
<a>
<b>
<c>
<d>
<e>
<f>
我也试过mapfile -d $'\0'
,但我的mapfile不支持-d
。
我确实发现这有效:
$ declare -a arr="( $(printf '"a\nb" "c" "d\ne\nf"') )"
$ for i in "${arr[@]}"; do printf "<%s>\n" "$i"; done
<a
b>
<c>
<d
e
f>
但是这看起来有点笨拙而且当我真正想让它告诉shell使用除了空格之外的某些字符作为数组字段分隔符时,我必须逃避"
。
答案 0 :(得分:5)
使用NUL分隔符的最佳实践方法:
arr=( )
while IFS= read -r -d '' item; do
arr+=( "$item" )
done < <(printf 'a\nb\n\0c\n\0d\ne\nf\n\0')
......使用bash 4.4会更简单:
mapfile -t -d '' arr < <(printf 'a\nb\n\0c\n\0d\ne\nf\n\0')
更粗略地说,支持双换行分离器方法:
item=''
array=( )
while IFS= read -r line; do
if [[ $line ]]; then
if [[ $item ]]; then
item+=$'\n'"$line"
else
item="$line"
fi
else
[[ $item ]] && {
array+=( "$item" )
item=''
}
fi
done < <(printf 'a\nb\n\nc\n\nd\ne\nf\n\n')