问题如下(这里我没有使用,find
因为它不支持双星号通配符**
):
$ FILES=(foo/**/*.suffix bar/**/*.suffix2)
$ grep baz "${FILES[@]}" # works
# I use this to create one local var with local in one function
$ SUBFILES="${FILES[@]}"
$ grep baz "${SUBFILES[@]}" # doesn't work
我曾经od
检查过它们,但它们是相同的,至少具有相同数量的“\n”和相同的长度(我没有逐个字符地检查。但乍一看它们是相同的)。
$ echo ${SUBFILES[@]} | od -c
$ echo ${FILES[@]} | od -c
为什么变量赋值不能创建一个对象但仍然有效grep
?
您说得对,
b="${a[@]}"
在 Bash 中不会创建数组。如果没有括号,那么无论右侧是什么,这都是标量赋值。因此,即使您使用索引@
分别请求所有数组项,赋值也会将它们强制为单个字符串。含义b="${a[@]}"
非常相似,b="${a[*]}"
只是它总是使用空格作为连接符,而不是 的第一个字符$IFS
。例如
要获取数组,您需要添加括号,即
b=( "${a[@]}" )
复制一个像您拥有的简单数组。我说“简单”,因为数组索引可以是不连续的,并且那里的扩展会丢失索引,而赋值会从 开始创建新的、连续的索引0
。如果您想要一个保留索引的副本,最安全的方法可能是使用循环。通常,变量也具有导出和整数属性等属性,您也必须手动重新设置它们。没有简单直接的方法来完整复制变量。
"${var@A}"
Bash 的新版本中有一个扩展,它提供了declare
重新创建变量的命令,但它包含原始名称,因此不能立即用于复制。我想你可以做这样的事情来复制d
到f
......但在现实生活中我会谨慎行事,无论如何,这都需要考虑原始变量的属性。例如,整数数组
g
将打印为declare -ai g=...
。请注意,
echo
它用空格连接它所获得的参数,因此echo ${a[@]}
或echo "${a[@]}"
隐藏了数组项之间的实际分隔位置。当标量赋值用空格连接时,和echo
用空格连接时,结果是这两种情况下的输出相同。这对于研究此类事情来说
echo
确实很不利。最好printf
在这里使用 eg,例如这可以更清楚地说明这b
只是一个元素。或者使用
typeset -p
/declare -p
。即使在 zsh 中,将
$a
其扩展为一个数组(用不同的项分隔),b=$a
仍然会连接到一个字符串,因此您需要知道您正在处理的变量的类型。 (b=$a[@]
是相同的,并且 zsh 使用 的第一个字符IFS
来表示@
和*
,与 Bash 略有不同。)数组赋值
bash
写在就你的情况来说,
这会将
FILES
数组的所有元素分配给数组SUBFILES
。将
SUBFILES="${FILES[@]}"
单个字符串分配给变量SUBFILES
。该字符串将包含以单个空格分隔的元素FILES
。另请参阅Shell 脚本中的变量是否有命名约定?