使用包含空格的元素创建Bash数组

时间:2017-06-01 19:26:37

标签: arrays bash shell

我无法理解在cygwin GNU bash上测试的这两个数组创建之间发生了什么

$ array=('hello world' how are you)
$ echo $array
'hello world'    <----- This is expected   
编辑:正如chepner指出输出

hello world      <----- no ''

现在将变量赋值作为中间步骤

$ words="'hello world' how are you"
$ echo $words
'hello world' how are you
$ array=($words)
$ echo $array
'hello           <----- Why was it split with ' '? 

6 个答案:

答案 0 :(得分:2)

来自Bash manual

Referencing an array variable without a subscript is equivalent to
referencing with a subscript of 0.

当您将单引号放在双引号内时,如:

words="'hello world' how are you"

单引号成为字符串的文字部分,因此在使用

初始化数组时不会阻止单词拆分
array=($words)

其中数组的第0个元素将变为'hello。要防止在这种情况下进行单词拆分,请执行以下操作:

array=("$words")

但是,这不会达到使hello world成为第0个元素的意图。直接分配array=('hello world' how are you)是正确的方法。

另见:

答案 1 :(得分:2)

codeforester's helpful answer很好地解释了这个问题。

至于 a 解决方案

注意:如果您正在处理的输入实际上没有嵌入式引用来划分元素,只需按原样使用readarray -t array < <(...) ,其中(...)表示产生输出的命令,其应作为数组的各个元素捕获。

xargs通常理解文字输入中的shell引用(转义,嵌入引号除外):

words="'hello world' how are you"
echo "$words" | xargs -n 1 printf '%s\n'
hello world
how
are
you

请注意hello world如何被识别为单个参数,以及如何将<{1}}实例移除

'中创建数组时使用此功能(由于bash假设Bash 4.x,但可以使其在Bash 3.x [1] ):

readarray

产生:

words="'hello world' how are you"
readarray -t array < <(xargs -n 1 printf '%s\n' <<<"$words")
declare -p array

(封闭的declare -a array=([0]="hello world" [1]="how" [2]="are" [3]="you") 实例是"输出格式的工件 - 如果要将输出重用为shell 源,它们具有语法功能代码。)

[1] Bash v3 +解决方案,使用declare -p代替read
readarray

答案 2 :(得分:0)

解除引用。试试这个:

$ array=('hello world' how are you)
$ echo $array
hello world
$ echo ${array[@]}
hello world how are you
$ echo ${array[0]}
hello world
$ echo ${array[1]}
how
$ echo ${array[2]}
are
$ echo ${array[3]}
you

答案 3 :(得分:0)

“在不提供索引号的情况下引用数组成员变量的内容与引用第一个元素的内容相同,第一个元素是索引号为零的引用。”来自this page,10.2.2节的最后一行

所以

$ echo $array

相当于

$ echo ${array[0]}

答案 4 :(得分:0)

在第一种情况下,单引号会阻止单词拆分以在两个参数中拆分hello world,单引号不会被回显

$ array=('hello world' how are you)
$ echo $array
hello world

在第二个中,引号是字符串文字,参数是分开的,这是不可见的,因为echo显示所有参数,如果使用printf "<%s>\n" $words,你会看到更好的

$ words="'hello world' how are you"
$ echo $words
'hello world' how are you
$ array=($words)
$ echo $array
'hello         

$ words="'hello world' how are you"
$ printf "<%s>\n" $words
<'hello>
<world'>
<how>
<are>
<you>

正如评论中所说,eval是危险的,你必须知道你在做什么

$ eval "array=($words)"
$ printf "<%s>\n" "${array[@]}"
<hello world>
<how>
<are>
<you>

答案 5 :(得分:0)

类似

$ array=($(echo -e $'a a\nb b' | tr ' ' '§')) && array=("${array[@]//§/ }") && echo "${array[@]/%/ INTERELEMENT}"

a a INTERELEMENT b b INTERELEMENT