如何在bash shell linux中交换数组元素?

4

我有一个关于数组元素交换的语法问题。

array="5 3 2 1 4"
echo "${array[*]}"

changed=1
while [ $changed != 0 ]
do
    changed=0
    for (( i=0 ; i<=${#array[@]}-1 ; i++ )) 
    do
        if [ ${array[$i]} -gt ${array[$i+1]} ]
            then
                tmp=${array[$i]}
                array[$i]=${array[$i+1]}
                array[$i+1]=$tmp
                changed=1
        fi
    done    
done

echo "Sorted array: "
echo "${array[*]}"

编辑:

感谢回答我的问题。我已经更改了代码,现在它看起来像这样。

但是不幸的是还有一个问题。

它显示:

jdoodle.sh: line 3: $'\r': command not found
jdoodle.sh: line 8: syntax error near unexpected token `$'\r''
jdoodle.sh: line 8: `    for ((i=0;i<=${#array[@]}-1;i++))

1
请看一下:http://www.shellcheck.net/ - Cyrus
对于shell中的算术运算,((...integer math...))是首选方法,结果本身使用$((...integer math...))letexpr也可以,但相比之下有一些限制)。注意:在bash中,对于索引数组${array[i]}for (( i=0 ; i<${#array[@]}; i++ ))已足够。但是,在索引内进行算术运算时,最好选择$((i+1)) - David C. Rankin
在编程中,赋值语句的等号两侧不要有空格。 - choroba
谢谢大家的回答,是的,我刚刚删除了不必要的空格。但现在我正在面临关于for循环过程的问题。:( 有什么建议吗?谢谢。 - J.John
你在使用Windows编辑器吗?Windows使用cr lf (\r\n)作为行尾;Linux和Unix只使用\n。请参阅man dos2unix - Ljm Dullaart
显示剩余2条评论
2个回答

3
这是冒泡排序的一个实现例子:
#!/bin/bash
array=(5 3 2 1 4)
echo "${array[*]}"

size=${#array[@]}

for (( i=0; i<size-1; i++ )); do

   for (( j=0; j<size-i-1; j++ )); do
      if (( array[j] > array[j+1] )); then
         tmp=${array[j]}
         array[j]=${array[j+1]}
         array[j+1]=$tmp
      fi
   done

done

echo "Sorted array:"
echo "${array[*]}"

你的代码主要问题在于它实际上没有使用数组。

定义数组的格式为array=(value1 value2 value3)。在测试时最好使用[[ ]]而不是[ ]。如果我们稍微修改一下你的代码,使其也能创建一个正常工作的冒泡排序算法,它可能会像这样:

#!/bin/bash
array=(5 3 2 1 4)
echo "${array[*]}"

changed=1 j=0

while [[ $changed != 0 ]]
do
    ((j++))
    changed=0
    for (( i=0; i<${#array[@]}-j; i++ )) 
    do  
        if [[ ${array[i]} -gt ${array[i+1]} ]]
        then
           tmp=${array[i]}
           array[i]=${array[i+1]}
           array[i+1]=$tmp
           changed=1
        fi  
    done        
done

echo "Sorted array:"
echo "${array[*]}"

你好!谢谢建议。我已经尝试使用https://www.jdoodle.com/test-bash-shell-script-online在线编译它。 - J.John
@J.John 为什么你要使用在线解释器进行测试呢? - PesaThe
嗨@PesaThe,因为我在我的笔记本电脑上没有安装Linux。 :) - J.John
@J.John 这段代码应该可以运行,你可以试一下其他的在线工具,例如 tutorialspoint 看起来很不错。 - PesaThe
@J.John,您可以获取busybox,无需安装。 - ctac_
@J.John MacOS 有 bash;在 Windows 上,您可以安装 Cygwin,就可以拥有所需的一切。 - xhienne

0

我无法收到 \r 消息,即使在您的测试环境中也是如此;通常,它们是 DOS/Windows 兼容性(带 b)的结果。

由于这显然是一个教程示例(否则为什么会有人做冒泡排序),因此对代码进行一些备注。

array="5 3 2 1 4"

不会创建你想要的数组,它只会创建一个字符串。你需要的是:

array=(5 3 2 1 4)

数组的最后一个元素是${#array[@]}-1。元素计数从0开始。因此,您的for循环应该是:
for (( i=0 ; i<=${#array[@]}-2 ; i++ )) 

-2 是因为你引用了 ${array[$i+1]},否则它会超出边界。


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