免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4152 | 回复: 5
打印 上一主题 下一主题

为感谢ChinaUnix上兄弟的无私帮助  关闭 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-04-14 23:37 |只看该作者 |倒序浏览
为感谢ChinaUnix上兄弟的无私帮助,我贡献一段关于shell数组的翻译,不足之处望大家海涵,海纳百川,有容乃大,希望大家尽己所能,发挥自由之精神。 (不知道刚才咋回事,发到Linux版了)

bash提供一维数组。使用一个数组前可以显式地以declare声明(言下之意,也可以不)。在数组元素的最大数目上并无约束,甚至,不要求数组元素被连续赋值。其下标从0开始。

一个数组可以通过如下赋值方式而自动创建:
name[subscript]=value
下标subscript必须为数,大于或等于0,显式声明如下:
declare -a name
为自己方便,也可写成
declare -a name[subscript],shell解释时忽略subscript.

用如下方式可对整个数组赋值
name=(value1 ... valuen)

其中value可用[subscript]=代替,从而具体指定对那个元素赋值。例子如下:

[shark@phi ver1.2]$ name=([0]=1 [2]=34 [3]=45)
[shark@phi ver1.2]$ echo ${name[0]}
1
[shark@phi ver1.2]$ echo ${name[1]}

[shark@phi ver1.2]$ echo ${name[2]}
34
[shark@phi ver1.2]$ echo ${name[3]}
45
[shark@phi ver1.2]$ echo ${name[4]}

[shark@phi ver1.2]$
(不过这样太不方便,个人意见,还不如按下标一个个写)
引用数组变量用
${name[subscript]}
必须用{},否则shell将有误解,而不予接受。

若下标为`@' or `*', 则做通配符解,代指所有数组元素。
[shark@phi ver1.2]$ echo ${name
  • }
    1 34 45
    [shark@phi ver1.2]$
    [shark@phi ver1.2]$ echo ${name[@]}
    1 34 45

    但不可做赋值
    name
  • =1    是错的。

    数组元素可以是字符串。元素间以环境变量IFS的第一个字符分隔。

    [shark@phi ver1.2]$ name=(hello glad to meet you)
    [shark@phi ver1.2]$ echo ${name[0]}
    hello
    [shark@phi ver1.2]$ echo ${name[1]}
    glad
    [shark@phi ver1.2]$ echo ${name[2]}
    to
    [shark@phi ver1.2]$ echo ${name[3]}
    meet
    [shark@phi ver1.2]$ echo ${name[4]}
    you

    若要跨过分隔约束,用双引号括起
    [shark@phi ver1.2]$ name=("hello glad" to meet you)
    [shark@phi ver1.2]$ echo ${name[0]}
    hello glad
    [shark@phi ver1.2]$ echo ${name[1]}
    to
    [shark@phi ver1.2]$ echo ${name[2]}
    meet
    [shark@phi ver1.2]$ echo ${name[3]}
    you

    数组元素个数以${#name[subscript]} 计得
    无下标的数组变量引用等价于引用其第零个元素。
    用unset命令可以销毁一个数组
    unset name    或者   unset name

  • 也可以只销毁一个元素
    unset name[subscript]

    read命令支持以 -a 参数从标准输入读入数组。
  • 论坛徽章:
    0
    2 [报告]
    发表于 2005-04-14 23:52 |只看该作者

    为感谢ChinaUnix上兄弟的无私帮助

    再灌一篇以供大家参考
    #!/bin/bash
    # array-ops.sh: More fun with arrays.


    array=( zero one two three four five )
    # Element 0   1   2    3     4    5

    echo ${array[0]}       #  zero
    echo ${array:0}        #  zero
                           #  Parameter expansion of first element,
                           #+ starting at position # 0 (1st character).
    echo ${array:1}        #  ero
                           #  Parameter expansion of first element,
                           #+ starting at position # 1 (2nd character).

    echo "--------------"

    echo ${#array[0]}      #  4
                           #  Length of first element of array.
    echo ${#array}         #  4
                           #  Length of first element of array.
                           #  (Alternate notation)

    echo ${#array[1]}      #  3
                           #  Length of second element of array.
                           #  Arrays in Bash have zero-based indexing.

    echo ${#array
  • }      #  6
                           #  Number of elements in array.
    echo ${#array[@]}      #  6
                           #  Number of elements in array.

    echo "--------------"

    array2=( [0]="first element" [1]="second element" [3]="fourth element" )

    echo ${array2[0]}      # first element
    echo ${array2[1]}      # second element
    echo ${array2[2]}      #
                           # Skipped in initialization, and therefore null.
    echo ${array2[3]}      # fourth element


    exit 0
  • 论坛徽章:
    0
    3 [报告]
    发表于 2005-04-14 23:59 |只看该作者

    为感谢ChinaUnix上兄弟的无私帮助

    不怕死,再灌#!/bin/bash
    # array-strops.sh: String operations on arrays.
    # Script by Michael Zick.
    # Used with permission.

    #  In general, any string operation in the ${name ... } notation
    #+ can be applied to all string elements in an array
    #+ with the ${name[@] ... } or ${name
  • ...} notation.


    arrayZ=( one two three four five five )

    echo

    # Trailing Substring Extraction
    echo ${arrayZ[@]:0}     # one two three four five five
                            # All elements.

    echo ${arrayZ[@]:1}     # two three four five five
                            # All elements following element[0].

    echo ${arrayZ[@]:1:2}   # two three
                            # Only the two elements after element[0].

    echo "-----------------------"

    #  Substring Removal
    #  Removes shortest match from front of string(s),
    #+ where the substring is a regular expression.

    echo ${arrayZ[@]#f*r}   # one two three five five
                            # Applied to all elements of the array.
                            # Matches "four" and removes it.

    # Longest match from front of string(s)
    echo ${arrayZ[@]##t*e}  # one two four five five
                            # Applied to all elements of the array.
                            # Matches "three" and removes it.

    # Shortest match from back of string(s)
    echo ${arrayZ[@]%h*e}   # one two t four five five
                            # Applied to all elements of the array.
                            # Matches "hree" and removes it.

    # Longest match from back of string(s)
    echo ${arrayZ[@]%%t*e}  # one two four five five
                            # Applied to all elements of the array.
                            # Matches "three" and removes it.

    echo "-----------------------"

    # Substring Replacement

    # Replace first occurance of substring with replacement
    echo ${arrayZ[@]/fiv/XYZ}   # one two three four XYZe XYZe
                                # Applied to all elements of the array.

    # Replace all occurances of substring
    echo ${arrayZ[@]//iv/YY}    # one two three four fYYe fYYe
                                # Applied to all elements of the array.

    # Delete all occurances of substring
    # Not specifing a replacement means 'delete'
    echo ${arrayZ[@]//fi/}      # one two three four ve ve
                                # Applied to all elements of the array.

    # Replace front-end occurances of substring
    echo ${arrayZ[@]/#fi/XY}    # one two three four XYve XYve
                                # Applied to all elements of the array.

    # Replace back-end occurances of substring
    echo ${arrayZ[@]/%ve/ZZ}    # one two three four fiZZ fiZZ
                                # Applied to all elements of the array.

    echo ${arrayZ[@]/%o/XX}     # one twXX three four five five
                                # Why?

    echo "-----------------------"


    # Before reaching for awk (or anything else) --
    # Recall:
    #   $( ... ) is command substitution.
    #   Functions run as a sub-process.
    #   Functions write their output to stdout.
    #   Assignment reads the function's stdout.
    #   The name[@] notation specifies a "for-each" operation.

    newstr() {
        echo -n "!!!"
    }

    echo ${arrayZ[@]/%e/$(newstr)}
    # on!!! two thre!!! four fiv!!! fiv!!!
    # Q.E.D: The replacement action is an 'assignment.'

    #  Accessing the "For-Each"
    echo ${arrayZ[@]//*/$(newstr optional_arguments)}
    #  Now, if Bash would just pass the matched string as $0
    #+ to the function being called . . .

    echo

    exit 0
  • 论坛徽章:
    0
    4 [报告]
    发表于 2005-04-15 00:07 |只看该作者

    为感谢ChinaUnix上兄弟的无私帮助

    啥时候结束,提醒一声,偶好收藏~~

    论坛徽章:
    1
    荣誉会员
日期:2011-11-23 16:44:17
    5 [报告]
    发表于 2005-04-15 00:08 |只看该作者

    为感谢ChinaUnix上兄弟的无私帮助

    原帖由 "gzgzgz" 发表:
    newstr optional_arguments)}
    #  Now, if Bash would just pass the matched string as $0
    #+ to the function being called . . .

    echo

    exit 0

        OK! learning ...

    论坛徽章:
    0
    6 [报告]
    发表于 2005-04-15 09:32 |只看该作者

    为感谢ChinaUnix上兄弟的无私帮助

    数组的向后扩展# Try extending those arrays.

    # Adding an element to an array.
    array0=( "${array0[@]}" "new1" )
    array1=( "${array1[@]}" "new1" )
    array2=( "${array2[@]}" "new1" )

    ListArray

    # or
    array0[${#array0
  • }]="new2"
    array1[${#array1
  • }]="new2"
    array2[${#array2
  • }]="new2

    数组的拷贝与合并

    #! /bin/bash
    # CopyArray.sh
    #
    # This script written by Michael Zick.
    # Used here with permission.

    #  How-To "ass by Name & Return by Name"
    #+ or "Building your own assignment statement".


    CpArray_Mac() {

    # Assignment Command Statement Builder

        echo -n 'eval '
        echo -n "$2"                    # Destination name
        echo -n '=( ${'
        echo -n "$1"                    # Source name
        echo -n '[@]} )'

    # That could all be a single command.
    # Matter of style only.
    }

    declare -f CopyArray                # Function "ointer"
    CopyArray=CpArray_Mac               # Statement Builder

    Hype()
    {

    # Hype the array named $1.
    # (Splice it together with array containing "Really Rocks".)
    # Return in array named $2.

        local -a TMP
        local -a hype=( Really Rocks )

        $($CopyArray $1 TMP)
        TMP=( ${TMP[@]} ${hype[@]} )
        $($CopyArray TMP $2)
    }

    declare -a before=( Advanced Bash Scripting )
    declare -a after

    echo "Array Before = ${before[@]}"

    Hype before after

    echo "Array After = ${after[@]}"

    # Too much hype?

    echo "What ${after[@]:3:2}?"

    declare -a modest=( ${after[@]:2:1} ${after[@]:3:2} )
    #                    ---- substring extraction ----

    echo "Array Modest = ${modest[@]}"

    # What happened to 'before' ?

    echo "Array Before = ${before[@]}"

    exit 0

    数组合并再一篇实例
    #! /bin/bash
    # array-append.bash

    # Copyright (c) Michael S. Zick, 2003, All rights reserved.
    # License: Unrestricted reuse in any form, for any purpose.
    # Version: $ID$
    #
    # Slightly modified in formatting by M.C.


    # Array operations are Bash-specific.
    # Legacy UNIX /bin/sh lacks equivalents.


    #  Pipe the output of this script to 'more'
    #+ so it doesn't scroll off the terminal.


    # Subscript packed.
    declare -a array1=( zero1 one1 two1 )
    # Subscript sparse ([1] is not defined).
    declare -a array2=( [0]=zero2 [2]=two2 [3]=three2 )

    echo
    echo '- Confirm that the array is really subscript sparse. -'
    echo "Number of elements: 4"        # Hard-coded for illustration.
    for (( i = 0 ; i < 4 ; i++ ))
    do
        echo "Element [$i]: ${array2[$i]}"
    done
    # See also the more general code example in basics-reviewed.bash.


    declare -a dest

    # Combine (append) two arrays into a third array.
    echo
    echo 'Conditions: Unquoted, default IFS, All-Elements-Of operator'
    echo '- Undefined elements not present, subscripts not maintained. -'
    # # The undefined elements do not exist; they are not being dropped.

    dest=( ${array1[@]} ${array2[@]} )
    # dest=${array1[@]}${array2[@]}     # Strange results, possibly a bug.

    # Now, list the result.
    echo
    echo '- - Testing Array Append - -'
    cnt=${#dest[@]}

    echo "Number of elements: $cnt"
    for (( i = 0 ; i < cnt ; i++ ))
    do
        echo "Element [$i]: ${dest[$i]}"
    done

    # Assign an array to a single array element (twice).
    dest[0]=${array1[@]}
    dest[1]=${array2[@]}

    # List the result.
    echo
    echo '- - Testing modified array - -'
    cnt=${#dest[@]}

    echo "Number of elements: $cnt"
    for (( i = 0 ; i < cnt ; i++ ))
    do
        echo "Element [$i]: ${dest[$i]}"
    done

    # Examine the modified second element.
    echo
    echo '- - Reassign and list second element - -'

    declare -a subArray=${dest[1]}
    cnt=${#subArray[@]}

    echo "Number of elements: $cnt"
    for (( i = 0 ; i < cnt ; i++ ))
    do
        echo "Element [$i]: ${subArray[$i]}"
    done

    #  The assignment of an entire array to a single element
    #+ of another array using the '=${ ... }' array assignment
    #+ has converted the array being assigned into a string,
    #+ with the elements separated by a space (the first character of IFS).

    # If the original elements didn't contain whitespace . . .
    # If the original array isn't subscript sparse . . .
    # Then we could get the original array structure back again.

    # Restore from the modified second element.
    echo
    echo '- - Listing restored element - -'

    declare -a subArray=( ${dest[1]} )
    cnt=${#subArray[@]}

    echo "Number of elements: $cnt"
    for (( i = 0 ; i < cnt ; i++ ))
    do
        echo "Element [$i]: ${subArray[$i]}"
    done
    echo '- - Do not depend on this behavior. - -'
    echo '- - This behavior is subject to change - -'
    echo '- - in versions of Bash newer than version 2.05b - -'

    # MSZ: Sorry about any earlier confusion folks.

    exit 0


    :em11: 冒泡排序

    #!/bin/bash
    # bubble.sh: Bubble sort, of sorts.

    # Recall the algorithm for a bubble sort. In this particular version...

    #  With each successive pass through the array to be sorted,
    #+ compare two adjacent elements, and swap them if out of order.
    #  At the end of the first pass, the "heaviest" element has sunk to bottom.
    #  At the end of the second pass, the next "heaviest" one has sunk next to bottom.
    #  And so forth.
    #  This means that each successive pass needs to traverse less of the array.
    #  You will therefore notice a speeding up in the printing of the later passes.


    exchange()
    {
      # Swaps two members of the array.
      local temp=${Countries[$1]} #  Temporary storage
                                  #+ for element getting swapped out.
      Countries[$1]=${Countries[$2]}
      Countries[$2]=$temp
      
      return
    }  

    declare -a Countries  #  Declare array,
                          #+ optional here since it's initialized below.

    #  Is it permissable to split an array variable over multiple lines
    #+ using an escape (\)?
    #  Yes.

    Countries=(Netherlands Ukraine Zaire Turkey Russia Yemen Syria \
    Brazil Argentina Nicaragua Japan Mexico Venezuela Greece England \
    Israel Peru Canada Oman Denmark Wales France Kenya \
    Xanadu Qatar Liechtenstein Hungary)

    # "Xanadu" is the mythical place where, according to Coleridge,
    #+ Kubla Khan did a pleasure dome decree.


    clear                      # Clear the screen to start with.

    echo "0: ${Countries
  • }"  # List entire array at pass 0.

    number_of_elements=${#Countries[@]}
    let "comparisons = $number_of_elements - 1"

    count=1 # Pass number.

    while [ "$comparisons" -gt 0 ]          # Beginning of outer loop
    do

      index=0  # Reset index to start of array after each pass.

      while [ "$index" -lt "$comparisons" ] # Beginning of inner loop
      do
        if [ ${Countries[$index]} \> ${Countries[`expr $index + 1`]} ]
        #  If out of order...
        #  Recalling that \> is ASCII comparison operator
        #+ within single brackets.

        #  if [[ ${Countries[$index]} > ${Countries[`expr $index + 1`]} ]]
        #+ also works.
        then
          exchange $index `expr $index + 1`  # Swap.
        fi  
        let "index += 1"
      done # End of inner loop

    # ----------------------------------------------------------------------
    # Paulo Marcel Coelho Aragao suggests for-loops as a simpler altenative.
    #
    # for (( last = $number_of_elements - 1 ; last > 1 ; last-- ))
    # do
    #     for (( i = 0 ; i < last ; i++ ))
    #     do
    #         [[ "${Countries[$i]}" > "${Countries[$((i+1))]}" ]] \
    #             && exchange $i $((i+1))
    #     done
    # done
    # ----------------------------------------------------------------------
      

    let "comparisons -= 1" #  Since "heaviest" element bubbles to bottom,
                           #+ we need do one less comparison each pass.

    echo
    echo "$count: ${Countries[@]}"  # Print resultant array at end of each pass.
    echo
    let "count += 1"                # Increment pass count.

    done                            # End of outer loop
                                    # All done.

    exit 0
    灌了这么多怕是要被斑竹打出去了
  • 您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP