2016-09-17 48 views
0

如何用多行命令输出填充bash数组?如何使用多行命令输出填充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',但我的映射文件不支持-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使用之外的其他一些字符作为数组字段分隔符空白。

+1

仅供参考''mapfile' in'bash' 4.4支持'-d'并于今天发布。 – chepner

回答

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')