我想将命令的输出存储到数组中。我尝试使用以下命令,该命令是从此处提出的类似问题中得到的。请在下面找到我使用的 shell 命令:
#!/bin/ksh
mailx -H >mytest.txt
#awk '/Incident/{ print NR;}' mytest.txt >lineNum.txt
msgNumbers=$(awk '/Incident/{ print NR;}' mytest.txt)
echo $msgNumbers
我可以在 UNIX 中直接执行此命令得到所需的结果。但是当我在 shell 脚本中使用相同的命令时,出现错误:
"syntax error at line 5: `msgNumbers=$' unexpected"
有人可以指出其中的错误吗?
答案1
如果您使用 Bourne shell 解释该脚本,就会出现这个错误,Bourne shell 是一种 70 年代非常古老的 shell,如今几乎不再使用,除非在 Solaris 10 及更早版本上。
所以我敢打赌,该脚本是/bin/sh
在 Solaris 10 或更早版本上解释的,而不是ksh
.在 Solaris 上,标准sh
采用/usr/xpg4/bin/sh
.
Bourne shell 不支持$(...)
命令替换的形式,您必须使用命令`...`
替换。
无论如何,Bourne shell 和 POSIXsh
规范都不支持数组。要将 Solaris 10 /bin/ksh
(基于 ksh88)命令输出的非空行内容分配给数组变量,您需要:
set -o noglob
IFS='
'
set -A array -- $(cmd)
(请注意,ksh88 数组的元素不能超过 4096 个)。
然后将数组的元素显示为:
((${#array[@]})) && printf '"%s"\n' "${array[@]}"
如果您的脚本有#!/bin/ksh
she-bang,则应将其调用为/path/to/the/script
or ksh /path/to/the/script
,而不是sh /path/to/the/script
。
答案2
要将命令输出的单独单词分配给 中的数组ksh
,您可以这样做
array=( $( mycommand ) )
这将运行mycommand
(在您的情况下是该awk
命令),并且该命令的输出将被拆分为空格上的单词(默认情况下是空格、制表符和换行符,这是IFS
shell 变量的内容)。然后 shell 还会对每个单词执行文件名生成(“globbing”),除非set -f
有效。
要输出这些元素,您可以使用
printf 'Element: %s\n' "${array[@]}"
或者
printf 'Elements: %s\n' "${array[*]}"
取决于您是想单独输出每个元素(第一个选项),还是一起输出每个元素,并用第一个字符分隔IFS
(第二个选项)。这样做echo $array
只会输出数组的第一个元素(而且,由于它没有被引用,因此将其分割为空格并执行文件名生成)。
或者,您可以只运行awk
命令,而无需尝试将输出存储在任何地方(因为这显然也会输出结果)。这取决于您想要对awk
命令结果执行的操作。