在我的 C-shell 脚本(特别是 tcsh)中,我一直试图声明一个具有六个值的数组:x、nx、y、ny、z、nz。经过一番尝试和错误后,我发现了三种不同的方式来声明我想要的数组:
set arrname = ("x" "nx" "y" "ny" "z" "nz")
set arrname = (x,nx,y,ny,z,nz)
set arrname = {x,nx,y,ny,z,nz}
但以下行不起作用:
set arrname = {"x" "nx" "y" "ny" "z" "nz"}
上面的行产生以下错误:
Missing }.
我的问题是 () 和 {} 之间有什么不同,导致我列出的第四个声明不起作用?
答案1
这:
set arrname = ("x" "nx" "y" "ny" "z" "nz")
是一个普通的数组赋值(顺便说一句,在这种情况下不需要引号)。
这:
set arrname = (x,nx,y,ny,z,nz)
也创建$arrname
一个数组,但它只有一个元素和值x,nx,y,ny,z,nz
(逗号在这种情况下并不特殊)。
这:
set arrname = {x,nx,y,ny,z,nz}
使用全局模式;正如{foo,bar}.txt
扩展到foo.txt bar.txt
,所以{x,nx,y,ny,z,nz}
扩展到x nx y ny z nz
。
显然 tcsh 允许您用作{x,nx,y,ny,z,nz}
数组初始化,但如果您自己将其扩展为:
set arrname = x nx y ny z nz
它设置$arrname
为 justx
并默默地忽略其他参数。这是 csh 和 tcsh 解析命令参数的方式中的许多奇怪故障之一。我自己使用 csh 和 tcsh 已有几十年了(尽管我最近主要改用 bash),而且我经常遇到这样的情况,我必须进行实验以确定某些东西将如何工作。
如果要设置$arrname
为数组值,请使用括号,然后不使用逗号。
正如巴马尔在评论中提到的,你应该阅读以下内容:
http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/
csh 和 tcsh 确实具有比 bash 更方便的数组语法。在 csh 和 tcsh 中,您可以将数组的第三个元素引用为$arrname[3]
;在 bash 中你必须添加大括号:${arrname[3]}
。此外,bash 数组是从 0 开始的,而 csh/tcsh 数组是从 1 开始的。但 bash 的语法和语义的更大一致性,恕我直言,足以弥补这一点。
csh 中的一些简单数组示例:
% set arr = ( 10 20 30 )
% echo $arr
10 20 30
% echo $arr[3]
30
在bash中:
$ arr=(10 20 30)
$ echo ${arr[@]}
10 20 30
$ echo ${arr[*]}
10 20 30
$ echo ${arr[2]}
30
([@]
和[*]
语法的行为略有不同;有关详细信息,请参阅 bash 文档。)
答案2
{} 是 shell 扩展,大括号扩展是一种可以生成任意字符串的机制。要进行大括号扩展的模式采用可选的 PREAMBLE 的形式,后跟一对大括号之间的一系列逗号分隔的字符串,最后是可选的 POSTSCRIPT。前导码作为大括号内包含的每个字符串的前缀,然后将附言附加到每个结果字符串,从左到右展开。详细链接
因此,如果您输入逗号,则不会出现丢失}
错误:
set arrname = {"x","nx","y","ny","z","nz"}