操作数预期 - Shell While循环
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了操作数预期 - Shell While循环相关的知识,希望对你有一定的参考价值。
大家好我试图在shell中冒泡排序,但我得到一个操作数预期错误。我初始化了我需要使用的变量,并确保我使用正确的语法(如果我没有,请纠正我)。我得到的错误是在这一行:
X = $ {阵列[$ i]于}
谢谢
#!/bin/bash
array=( "$@" )
#echo ${array[@]} print all elements in the array
if [ $# -gt 9 ]
then
echo Too many arguments, run the program over again
exit
fi
echo $array
i=0
j=0
#for j in { $j -lt ${#array[@]-1} } #((j = 0; j < $@ - 1}; j++))
while [ $j -lt ${#array[@]-1} ]
do
for i in {$array}
#for((i=0; i< array; i++))
do
x=${array[$i]}
y=${array[$i]+1}
if [ $x -gt $y ]
temp=${array[$i]}
${array[$i]}=${array[$i+1]}
${array[$i+1]}=$temp
fi
done
done
echo "Sorted Array: " ${array[@]}
#if ((array[i] > array[i+1]))
#if((x>y))
#if [ ${array[$i]} -gt ${array[$i]+1} ]
在这个脚本中有很多地方你可以通过足够的语法来完成与你想要的完全不同的事情。为了演示这些问题,让我初始化几个变量:
$ array=(15 22 30 93 27)
$ i=2
好的,第一个问题命令是echo $array
。这只打印数组的第一个元素;要打印所有元素,请使用echo "${array[@]}"
。请注意,我在它周围添加了双引号 - 围绕变量引用的双引号几乎总是一个好主意,以避免单词拆分和通配符扩展的意外影响。当我说“好主意”时,我的意思是“如果你不这样做,当你测试它时,它可能会完美地工作,然后一段时间后会出现一个奇怪的错误,你将不知道是什么继续,直到你将问题跟踪到一个应该被双引号的变量引用。双引号变量引用只是很好的脚本卫生。无论如何,这是一个不正确的阵列打印的快速演示:
$ echo $array # wrong
15
$ echo "${array[@]}" # right
15 22 30 93 27
其次,在while [ $j -lt ${#array[@]-1} ]
中,“-1”处于bash不进行数学运算的地方。通常,在${ }
中,-something
表示如果未定义变量,则应使用“ - ”之后的事物。在这里,它基本上被忽略了:
$ echo "${#array[@]-1}" # wrong
5
$ echo "${#array[@]}" # equivalent, still wrong
5
为了做数学,你需要进入算术上下文。你可以用$(( ))
做到这一点:
$ echo "$(( ${#array[@]} - 1 ))" # right
4
...但在这种情况下,使用算术测试表达式(( ))
而不是使用[ ]
进行简单测试会更简单。请注意,[ ]
和(( ))
之间的比较运算符是不同的,并且您不必使用$
来获取变量的值;它出来像这样:
while (( j < ${#array[@]} - 1 )) # right
好吧,除了你不在循环中增加j
,所以它只是无休止地迭代。要么在循环中添加((j++))
,要么使用for
循环。你在评论中有这种方法,但你也需要在那里进行相同的语法修正:
for ((j = 0; j < ${#array[@]} - 1; j++)) # also right
实际上,还有另一种方法可以做到这一点;你可以使用${!array[@]}
来获取数组的索引列表(“!”使它给出索引,而不是内容):
for j in "${!array[@]}" # still right
下一个问题:在for i in {$array}
中,它只是获取数组的第一个元素,并在其周围放置一个“{}”:
$ echo "{$array}" # wrong
{15}
这基本上与外部while
/ for
循环做同样的事情,因此任何这些解决方案都可以在这里工作。
接下来,y=${array[$i]+1}
- 再次,这不是算术背景,所以+
没有做你期望的。在${ }
中,+something
的意思是“如果变量被定义,则使用值'某事'”。由于定义了array
,因此总是将y
设置为“1”。要解决这个问题,只需将+1
放入[ ]
(这是算术上下文,因此数学运算)。另外,你可以在$
上放弃i
,因为它是一个算术上下文,变量引用是自动的:
$ echo "${array[$i]+1}" # wrong
1
$ echo "${array[i+1]}" # right
93
接下来,为了比较if [ $x -gt $y ]
,if
需要一个then
(在下一行或由分号分隔的同一行:
if [ $x -gt $y ]; then # right
if [ $x -gt $y ]
then # also right
顺便说一句,你在附近的评论中使用的if ((array[i] > array[i+1]))
可以很好地获取和比较数组元素。如果你使用then
。
好的,最后的问题:在${array[$i]}=${array[$i+1]}
中,你告诉bash获取数组的i
th元素中的值,并将该名称的变量设置为下一个元素的值。嗯,有点,它实际上甚至比那更奇怪。无论如何,问题在于,当分配给数组元素时,不要将其包装在${ }
中:
$ ${array[$i]}=${array[$i+1]} # wrong
-bash: 30=93: command not found
$ array[$i]=${array[$i+1]} # right
$ array[i]=${array[i+1]} # also right
for i in {$array}
由数组元素循环,因此$i
是一个字符串,而不是索引。要按索引循环,您需要:
for ((i=0; i<${#array[*]}; i++));
do
x=${array[i]}
y=${array[i+1]}
if [ $x -gt $y ]
temp=${array[i]}
${array[i]}=${array[i+1]}
${array[i+1]}=$temp
fi
done
请注意,您不需要在$
前面使用i
标志。
此外,还有内置的排序方式;例如,see the answers here。
以上是关于操作数预期 - Shell While循环的主要内容,如果未能解决你的问题,请参考以下文章