Tcsh

C Shell 數組聲明語法,() vs {}

  • September 24, 2014

在我的 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 }.

我的問題是 () 和 {} 之間有什麼不同使我列出的第四個聲明不起作用?

{} 是外殼擴展,大括號擴展是一種可以生成任意字元串的機制。要進行大括號擴展的模式採用可選 PREAMBLE 的形式,後跟一對大括號之間的一系列逗號分隔的字元串,然後是可選的 POSTSCRIPT。序言作為前綴添加到大括號中包含的每個字元串,然後將後記附加到每個結果字元串,從左到右擴展。詳細連結

所以,如果你把逗號那麼你就不會失去}錯誤:

  set arrname = {"x","nx","y","ny","z","nz"}

這:

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為公正x並默默地忽略其他參數。這是 csh 和 tcsh 解析命令參數的方式中的許多奇怪故障之一。我自己已經使用 csh 和 tcsh 幾十年了(儘管我最近主要轉向 bash),並且我經常遇到這樣的情況,我必須通過實驗來確定某些東西是如何工作的。

如果要設置$arrname為數組值,請使用括號,不要使用逗號。

正如評論中提到的barmar,您應該閱讀以下內容:

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

[@]and[*]語法的行為略有不同;有關詳細資訊,請參閱 bash 文件。)

引用自:https://unix.stackexchange.com/questions/80934