如何在bash中连接数组?
Posted
技术标签:
【中文标题】如何在bash中连接数组?【英文标题】:How to concatenate arrays in bash? 【发布时间】:2015-09-17 13:56:05 【问题描述】:我是 Bash 的新手。我有一个从标准输入获取输入的数组。我必须将自己连接两次。说,我在数组中有以下元素:
Namibia
Nauru
Nepal
Netherlands
NewZealand
Nicaragua
Niger
Nigeria
NorthKorea
Norway
现在,输出应该是:
Namibia Nauru Nepal Netherlands NewZealand Nicaragua Niger Nigeria NorthKorea Norway Namibia Nauru Nepal Netherlands NewZealand Nicaragua Niger Nigeria NorthKorea Norway
我的代码是:
countries=()
while read -r country; do
countries+=( "$country" )
done
countries=countries+countries+countries # this is the wrong way, i want to know the right way to do it
echo "$countries[@]"
请注意,我可以像下面的代码一样打印三次,但这不是我的座右铭。我必须将它们连接到数组中。
countries=()
while read -r country; do
countries+=( "$country" )
done
echo "$countries[@] $countries[@] $countries[@]"
【问题讨论】:
您已经在自己的代码中添加了数组... @HuStmpHrrr,将单个项目附加到一个数组(通过附加一个单值数组),是的,但我可以理解为什么有人不理解他们已经使用的语法。 但我不知道,如何添加自己。谢谢。 @HuStmpHrrr 【参考方案1】:首先,将您的列表读入一个数组,每行一个条目:
readarray -t countries
...或者,使用旧版本的 bash:
# same, but compatible with bash 3.x; || is to avoid non-zero exit status.
IFS=$'\n' read -r -d '' countries || (( $#countries[@] ))
其次,要复制条目,要么将数组扩展到自身三倍:
countries=( "$countries[@]" "$countries[@]" "$countries[@]" )
...或使用现代语法执行追加:
countries+=( "$countries[@]" "$countries[@]" )
【讨论】:
当像上一个例子那样连接数组时,为什么不使用"$countries[*]"
(而不是像打印时那样使用"$countries[@]"
)?
@jww,使用 "$countries[*]"
将仅添加 一个 数组元素,该数组元素包含一个字符串,整个国家列表连接在一起,而不是每个国家一个元素。
@jww, ...而相比之下,不带引号的$countries[*]
将更改名称中带有空格的国家/地区——比如New Guinea
——将每个单词分隔到自己的列表中元素(为New
和Guinea
中的每一个添加一个单独的数组元素)。【参考方案2】:
在 ubuntu 14.04 上,以下将连接三个元素(元素计数将给出:3),每个元素是一个数组 countries
:
countries=( "$countries[@]" "$countries[@]" "$countries[@]" )
而下面的代码会将所有元素连接到一个数组中:
countries=( $countries[*] $countries[*] $countries[*] )
这个计数将是 30(考虑到原始帖子中指定的国家/地区)。
【讨论】:
这是错误的。countries=( "$countries[@]" "$countries[@]" "$countries[@]" )
将原始数组扩展 3 次,每个原始数组元素创建一个元素,每 3 次。 countries=( $countries[*] $countries[*] $countries[*] )
,相比之下,string-splits 和 glob-expands 原始数组。假设你有countries=( "New Guinea" "New Zealand" "North Korea" )
; result=( "$countries[@]" "$countries[@]" "$countries[@]" )
扩展到九个项目。
相比之下,result=( $countries[*] $countries[*] $countries[*] )
扩展为 18 项,因为每个 New
都成为自己的数组元素。 (如果它拆分成的任何一个单词都是可以匹配本地磁盘上文件的glob,那就更复杂了!)
...查看此代码在在线解释器中运行,其输出位于ideone.com/Bj9LLM【参考方案3】:
简单地写这个:
countries=$(cat)
countries+=( "$countries[@]" "$countries[@]" )
echo $countries[@]
第一行是输入数组,第二行是连接,最后是打印数组。
【讨论】:
countries=$(cat)
将从标准输入获取的单个字符串分配给数组的第一个元素;个别元素没有分解到个别国家。 (使用declare -p countries
显示数组的定义,行为会很明显)。
...也就是说,当你这样做时,你的数组不是countries=( A B C A B C A B C )
而是countries=( "A B C" "A B C" "A B C" )
;根本看不出这是一个问题,因为使用中的echo
命令引用不充分,因此拆分了它的参数。使用printf '%q\n' "$countries[@]"
,每个集合将位于不同的行,这同样会使问题可见(而如果正确填充数组,每个 country 将位于不同的行)。跨度>
以上是关于如何在bash中连接数组?的主要内容,如果未能解决你的问题,请参考以下文章