Csh如何将字符串添加到数组中,空格问题

6

我在使用csh时遇到了一些基本问题。我有一个字符串:

set newCmd = "$expansionCmd –option1 –option2 …"

我正在创建一个这些字符串的数组,之后我想要执行它们:

set expansionCmdList = ($expansionCmdList[*] "$newCmd")   
#I also tried without quotes, e.g. just $newCmd

最后,我尝试迭代并执行这些命令:
foreach exCmd ($expansionCmdList) 
    `exCmd`    #execute it in the shell
end 

然而问题在于数组条目不是完整的字符串,而是由空格分隔的每个字符串部分,即第一个条目只是“$expansionCmd”,下一个条目将是“—option1”等。
提前为使用c shell道歉,我的公司代码库被困在其中。
2个回答

10
无论何时您扩展整个数组并希望保持其各个元素的标识不变,您需要在扩展中使用:q(表示“引用”)修饰符。否则,一旦您执行类似于set expansionCmdList=($expansionCmdList[*] "$newCmd")的操作,列表中的所有先前命令都会被拆分为其组成单词,每个单词现在都是其自己的数组元素。简单演示:
% set a = ( a "b c" d )
% echo $a[2]
b c
% set a = ( $a[*] e )
% echo $a[2]
b

糟糕,你在执行循环之前就把数组搞砸了。使用:q会更顺利:

% set a = ( a "b c" d )
% set a = ( $a:q e )
% echo $a[2]
b c

在for循环中,你需要使用相同的修饰符:

foreach exCmd ($expansionCmdList:q) 

最后,`exCmd` 尝试字面上运行一个名为 "exCmd" 的命令,然后获取其输出并将其作为命令运行。你可能想要做的是执行与变量值相等的命令。在这里,您可能会遇到更多的空格问题,并且无法通过使每个命令成为数组来解决它们,因为 csh 不支持数组的数组。请注意。但如果命令不需要引号,则可以使用以下方法:

  $exCmd

2
谢谢,伙计...我发誓我能找到的唯一关于c shell的文档就是人们说不要使用c shell。 - JDS
1
唯一重要的原因不使用csh进行脚本编写的是,csh不是一个非常好的脚本语言...这是由于你必须把别名扭曲成结,以便具有任何类型的子程序功能。但如果那就是你所拥有的,那就是你所拥有的。而且它在POSIX shell之前就已经拥有了数组和内置算术运算符。 :) - Mark Reed
请注意,使用${array}:q是无效的,正确的写法应该是$arr:q - Sean Allred
1
@SeanAllred 当然。${array}:q 专门使用花括号来防止修饰符的应用,并在结果中获得字面上的 :q。如果您想使用花括号并仍然应用修饰符,则为 ${array:q} - Mark Reed

1

对于大多数应用来说,Mark的解决方案显然更优,但还有另一种选择。不直接使用foreach,而是获取数组的大小并遍历序列:

set BUILD_MATRIX = ( "makefile.make:make --jobs --makefile=makefile.make" \
                     "Makefile:make --jobs --makefile=Makefile" \
                     "build.xml:ant" )

foreach i ( `seq ${#BUILD_MATRIX}` )
  echo $i
  echo $BUILD_MATRIX[$i]
end

(从TCSH中访问带空格的数组元素复制)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接