【问题标题】:Arrays in unix shell?unix shell中的数组?
【发布时间】:2018-11-21 16:05:59
【问题描述】:

如何在 unix shell 脚本中创建数组?

【问题讨论】:

标签: arrays bash shell unix


【解决方案1】:

以下代码在 shell 中创建并打印一个字符串数组:

#!/bin/bash
array=("A" "B" "ElementC" "ElementE")
for element in "${array[@]}"
do
    echo "$element"
done

echo
echo "Number of elements: ${#array[@]}"
echo
echo "${array[@]}"

结果:

A
B
ElementC
ElementE

Number of elements: 4

A B ElementC ElementE

【讨论】:

    【解决方案2】:

    在 bash 中,你可以像这样创建数组

    arr=(one two three)
    

    调用元素

    $ echo "${arr[0]}"
    one
    $ echo "${arr[2]}"
    three
    

    要询问用户输入,您可以使用 read

    read -p "Enter your choice: " choice
    

    【讨论】:

    • 空格分隔的声明不适用于/bin/sh,引发错误line 1: syntax error: unexpected "("。你知道替代方案吗?
    【解决方案3】:

    Bourne shell 不支持数组。但是,有两种方法可以处理此问题。

    使用位置 shell 参数 $1、$2 等:

    $ set one two three
    $ echo $*
    one two three
    $ echo $#
    3
    $ echo $2
    two
    

    使用变量评估:

    $ n=1 ; eval a$n="one" 
    $ n=2 ; eval a$n="two" 
    $ n=3 ; eval a$n="three"
    $ n=2
    $ eval echo \$a$n
    two
    

    【讨论】:

    • Bash 支持数组。不确定原始的 Bourne shell,但 bash 近来更为流行......
    • @zplesivcak - ... 在 GNU/Linux 上,因为它是 GNU 的东西。例如,FreeBSD 不附带bash(虽然它可以从端口安装)。假设bash 功能编写的脚本不可移植,而且它们明显慢于大多数 Bourne shell 实现(如dash,这在 GNU/Linux 发行版中很常见)。 bash 是一个不错的交互式 shell,但编写脚本很慢。
    • $* 被认为是有害的。通常,$@ 是首选,因为它的作用相同,但会保留空格。 $@ 扩展为 "$1" "$2" "$3" ... "$n",而 $* 扩展为 "$1x$2x$3x...$n",其中 x 为 @ 987654332@ 分隔符(很可能是空格)。
    • 未引用,$@$* 相同;差异仅在引用时显示:"$*" 是一个单词,而 "$@" 保留原始单词中断。
    • 问题被标记为bash,因此针对 bash 的响应是合适的,但确实不应该假设 /bin/sh 是 bash。
    【解决方案4】:
    #!/bin/bash
    
    # define a array, space to separate every item
    foo=(foo1 foo2)
    
    # access
    echo "${foo[1]}"
    
    # add or changes
    foo[0]=bar
    foo[2]=cat
    foo[1000]=also_OK
    

    您可以阅读 ABS 《高级 Bash 脚本指南》

    【讨论】:

    • 请重新考虑建议将 ABS 作为学习资源——它在很多方面都在抨击 W3Schools 对 HTML 和 Javascript 的影响,有很多 Google 果汁,但在许多示例中展示了不良做法,而且很少并且更新不充分。 The bash-hackers' wiki 是一个更好的资源; BashGuide 也是如此。
    • 空格分隔的声明不适用于/bin/sh,引发错误line 1: syntax error: unexpected "("。你知道替代方案吗?
    【解决方案5】:

    Bourne shell 和 C shell 没有数组,IIRC。

    除了别人说的,在Bash中你可以得到数组中的元素个数如下:

    elements=${#arrayname[@]}
    

    并进行切片式操作:

    arrayname=(apple banana cherry)
    echo ${arrayname[@]:1}                   # yields "banana cherry"
    echo ${arrayname[@]: -1}                 # yields "cherry"
    echo ${arrayname[${#arrayname[@]}-1]}    # yields "cherry"
    echo ${arrayname[@]:0:2}                 # yields "apple banana"
    echo ${arrayname[@]:1:1}                 # yields "banana"
    

    【讨论】:

    • csh 确实有数组。
    • @KeithThompson:man page 中没有记录,但至少在某些版本中似乎确实存在该功能。
    • 手册页没有提到该名称的“数组”,但请参阅set 命令(set name=(wordlist))和“变量替换”部分($name[selector] 和 @ 987654327@)。据我所知,csh 一直支持数组。例如,请参见 $path 数组变量,它反映了 $PATH 环境变量。
    【解决方案6】:

    试试这个:

    echo "Find the Largest Number and Smallest Number of a given number"
    echo "---------------------------------------------------------------------------------"
    echo "Enter the number"
    read n
    i=0
    
    while [ $n -gt 0 ] #For Seperating digits and Stored into array "x"
    do
            x[$i]=`expr $n % 10`
            n=`expr $n / 10`
            i=`expr $i + 1`
    done
    
    echo "Array values ${x[@]}"  # For displaying array elements
    
    
    len=${#x[*]}  # it returns the array length
    
    
    for (( i=0; i<len; i++ ))    # For Sorting array elements using Bubble sort
    do
        for (( j=i+1; j<len;  j++ ))
        do
            if [ `echo "${x[$i]} > ${x[$j]}"|bc` ]
            then
                    t=${x[$i]}
                    t=${x[$i]}
                    x[$i]=${x[$j]}
                    x[$j]=$t
            fi
            done
    done
    
    
    echo "Array values ${x[*]}"  # Displaying of Sorted Array
    
    
    for (( i=len-1; i>=0; i-- ))  # Form largest number
    do
       a=`echo $a \* 10 + ${x[$i]}|bc`
    done
    
    echo "Largest Number is : $a"
    
    l=$a  #Largest number
    
    s=0
    while [ $a -gt 0 ]  # Reversing of number, We get Smallest number
    do
            r=`expr $a % 10`
            s=`echo "$s * 10 + $r"|bc`
            a=`expr $a / 10`
    done
    echo "Smallest Number is : $s" #Smallest Number
    
    echo "Difference between Largest number and Smallest number"
    echo "=========================================="
    Diff=`expr $l - $s`
    echo "Result is : $Diff"
    
    
    echo "If you try it, We can get it"
    

    【讨论】:

      【解决方案7】:

      您的问题涉及“unix shell 脚本”,但标记为bash。这是两个不同的答案。

      shell 的 POSIX 规范对数组没有任何规定,因为最初的 Bourne shell 不支持它们。即使在今天,在 FreeBSD、Ubuntu Linux 和许多其他系统上,/bin/sh 也不支持阵列。因此,如果您希望您的脚本在不同的 Bourne 兼容 shell 中工作,则不应使用它们。或者,如果您假设一个特定的外壳,那么请确保将其全名放在 shebang 行中,例如#!/usr/bin/env bash.

      如果您使用的是bashzsh,或者ksh 的现代版本,您可以像这样创建一个数组:

      myArray=(first "second element" 3rd)
      

      并访问这样的元素

      $ echo "${myArray[1]}" # for bash/ksh; for zsh, echo $myArray[2]
      second element
      

      您可以通过"${myArray[@]}" 获取所有元素。您可以使用切片符号 ${array[@]:start:length} 来限制引用的数组部分,例如"${myArray[@]:1}" 省略第一个元素。

      数组的长度是${#myArray[@]}。您可以使用"${!myArray[@]}" 从现有数组中获取包含所有索引的新数组。

      ksh93 之前的旧版本 ksh 也有数组,但没有基于括号的表示法,也不支持切片。不过,您可以像这样创建一个数组:

      set -A myArray -- first "second element" 3rd 
      

      【讨论】:

        【解决方案8】:

        您可以尝试以下类型:

        #!/bin/bash
         declare -a arr
        
         i=0
         j=0
        
          for dir in $(find /home/rmajeti/programs -type d)
           do
                arr[i]=$dir
                i=$((i+1))
           done
        
        
          while [ $j -lt $i ]
          do
                echo ${arr[$j]}
                j=$((j+1))
          done
        

        【讨论】:

        • 用空格分隔目录名称。使用更改 IFS 的 while 读取循环来处理。
        【解决方案9】:

        数组可以通过两种方式加载。

        set -A TEST_ARRAY alpha beta gamma
        

        X=0 # Initialize counter to zero.
        

        -- 使用字符串 alpha、beta 和 gamma 加载数组

        for ELEMENT in alpha gamma beta
        do
            TEST_ARRAY[$X]=$ELEMENT
            ((X = X + 1))
        done
        

        另外,我认为以下信息可能会有所帮助:

        shell 支持一维数组。最大数组数 元素为 1,024。定义数组时,它会自动 尺寸为 1,024 个元素。一维数组包含一个 数组元素的序列,就像连接的棚车 一起在火车轨道上。

        如果你想访问数组:

        echo ${MY_ARRAY[2] # Show the third array element
         gamma 
        
        
        echo ${MY_ARRAY[*] # Show all array elements
        -   alpha beta gamma
        
        
        echo ${MY_ARRAY[@] # Show all array elements
         -  alpha beta gamma
        
        
        echo ${#MY_ARRAY[*]} # Show the total number of array elements
        -   3
        
        
        echo ${#MY_ARRAY[@]} # Show the total number of array elements
        -   3
        
        echo ${MY_ARRAY} # Show array element 0 (the first element)
        -  alpha
        

        【讨论】:

          【解决方案10】:

          如果您想要一个支持空格的键值存储,请使用-A 参数:

          declare -A programCollection
          programCollection["xwininfo"]="to aquire information about the target window."
          
          for program in ${!programCollection[@]}
          do
              echo "The program ${program} is used ${programCollection[${program}]}"
          done
          

          http://linux.die.net/man/1/bash "关联数组是使用 declare -A name 创建的。"

          【讨论】:

            【解决方案11】:

            有多种方法可以在 shell 中创建数组。

            ARR[0]="ABC"
            ARR[1]="BCD"
            echo ${ARR[*]}
            

            ${ARR[*]} 打印数组中的所有元素。

            第二种方法是:

            ARR=("A" "B" "C" "D" 5 7 "J")
            echo ${#ARR[@]}
            echo ${ARR[0]}
            

            ${#ARR[@]}用于计算数组的长度。

            【讨论】:

            • 不错的答案,对于新手来说是一个很好的开始。并欢迎投票水平 ;-)
            【解决方案12】:

            从键盘读取值并将元素插入数组

            # enter 0 when exit the insert element
            echo "Enter the numbers"
            read n
            while [ $n -ne 0 ]
            do
                x[$i]=`expr $n`
                read n
                let i++
            done
            
            #display the all array elements
            echo "Array values ${x[@]}"
            echo "Array values ${x[*]}"
            
            # To find the array length
            length=${#x[*]}
            echo $length
            

            【讨论】:

              【解决方案13】:

              一个简单的方法:

              arr=("sharlock"  "bomkesh"  "feluda" )  ##declare array
              
              len=${#arr[*]}  #determine length of array
              
              # iterate with for loop
              for (( i=0; i<len; i++ ))
              do
                  echo ${arr[$i]}
              done
              

              【讨论】:

                【解决方案14】:

                在 ksh 中你这样做:

                set -A array element1 element2 elementn
                
                # view the first element
                echo ${array[0]}
                
                # Amount elements (You have to substitute 1)
                echo ${#array[*]}
                
                # show last element
                echo ${array[ $(( ${#array[*]} - 1 )) ]}
                

                【讨论】:

                • 显示最后一个元素的更简洁的方法是echo "${array[@]:(-1)}"。这样就不需要写两次数组变量名了。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2013-05-12
                • 2020-03-26
                • 1970-01-01
                • 2015-03-12
                • 1970-01-01
                • 2010-09-15
                相关资源
                最近更新 更多