Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何在Bash中切片数组_Arrays_Bash_Slice - Fatal编程技术网

Arrays 如何在Bash中切片数组

Arrays 如何在Bash中切片数组,arrays,bash,slice,Arrays,Bash,Slice,查看bash(1)手册页中的“Array”部分,我没有找到分割数组的方法 所以我提出了一个过于复杂的函数: #!/bin/bash # @brief: slice a bash array # @arg1: output-name # @arg2: input-name # @args: seq args # ---------------------------------------------- function slice() { local output=$1 lo

查看bash(1)手册页中的“Array”部分,我没有找到分割数组的方法

所以我提出了一个过于复杂的函数:

#!/bin/bash

# @brief: slice a bash array
# @arg1:  output-name
# @arg2:  input-name
# @args:  seq args
# ----------------------------------------------
function slice() {
   local output=$1
   local input=$2
   shift 2
   local indexes=$(seq $*)

   local -i i
   local tmp=$(for i in $indexes 
                 do echo "$(eval echo \"\${$input[$i]}\")" 
               done)

   local IFS=$'\n'
   eval $output="( \$tmp )"
}
这样使用:

$ A=( foo bar "a  b c" 42 )
$ slice B A 1 2
$ echo "${B[0]}"  # bar
$ echo "${B[1]}"  # a  b c
有更好的方法吗?

请参阅Bash
man
页面中的部分
A[@]
返回数组的内容,
:1:2
从索引1开始获取长度为2的切片

A=( foo bar "a  b c" 42 )
B=("${A[@]:1:2}")
C=("${A[@]:1}")       # slice to the end of the array
echo "${B[@]}"        # bar a  b c
echo "${B[1]}"        # a  b c
echo "${C[@]}"        # bar a  b c 42
echo "${C[@]: -2:2}"  # a  b c 42 # The space before the - is necesssary

请注意,
abc
是一个数组元素(并且它包含一个额外的空间)这一事实被保留。

还有一个方便的快捷方式,可以从指定的索引开始获取数组的所有元素。例如,${A[@]:1}将是数组的“尾”,即没有第一个元素的数组

version=4.7.1
A=( ${version//\./ } )
echo "${A[@]}"    # 4 7 1
B=( "${A[@]:1}" )
echo "${B[@]}"    # 7 1

类似Python中的数组切片(来自库):

array_slice(){
本地文件
返回数组的一个片段(类似于Python)。
从Python文档中:
记住切片工作原理的一种方法是将索引视为指向
在元素之间,第一个字符的左边缘编号为0。
那么长度为n的数组的最后一个元素的右边缘
索引n,例如:
```
+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 |
+---+---+---+---+---+---+
0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1
```
>>>局部a=(01 2 3 4 5)
>>>echo$(array.slice 1:-2“${a[@]}”)
1 2 3
>>>局部a=(01 2 3 4 5)
>>>echo$(array.slice 0:1“${a[@]}”)
0
>>>局部a=(01 2 3 4 5)
>>>[-z“$(array.slice 1:1“${a[@]}”)”]&回显为空
空的
>>>局部a=(01 2 3 4 5)
>>>[-z“$(array.slice 2:1“${a[@]}”)”]&回显为空
空的
>>>局部a=(01 2 3 4 5)
>>>[-z“$(array.slice-2:-3“${a[@]}”)”]&回显为空
空的
>>>[-z“$(array.slice-2:-2“${a[@]}”)”]&回显为空
空的
切片索引具有有用的默认值;省略的第一个索引默认为
如果为零,则省略的第二个索引默认值为所选字符串的大小
切片。
>>>局部a=(01 2 3 4 5)
>>>#从开始到位置2(不包括在内)
>>>echo$(array.slice 0:2“${a[@]}”)
>>>echo$(array.slice:2“${a[@]}”)
0 1
0 1
>>>局部a=(01 2 3 4 5)
>>>#从位置3(包括)到末端
>>>echo$(array.slice 3:“${a[@]}”“${a[@]}”)
>>>echo$(array.slice 3:“${a[@]}”)
3 4 5
3 4 5
>>>局部a=(01 2 3 4 5)
>>>#从倒数第二个(包括)到最后一个
>>>echo$(array.slice-2:“${a[@]}”“${a[@]}”)
>>>echo$(array.slice-2:“${a[@]}”)
4 5
4 5
>>>局部a=(01 2 3 4 5)
>>>echo$(array.slice-4:-2“${a[@]}”)
2 3
如果没有给定范围,则其工作方式与正常数组索引类似。
>>>局部a=(01 2 3 4 5)
>>>echo$(array.slice-1“${a[@]}”)
5.
>>>局部a=(01 2 3 4 5)
>>>echo$(array.slice-2“${a[@]}”)
4.
>>>局部a=(01 2 3 4 5)
>>>echo$(array.slice 0“${a[@]}”)
0
>>>局部a=(01 2 3 4 5)
>>>echo$(array.slice 1“${a[@]}”)
1.
>>>局部a=(01 2 3 4 5)
>>>array.slice 6“${a[@]}”;echo$?
1.
>>>局部a=(01 2 3 4 5)
>>>array.slice-7“${a[@]}”;echo$?
1.
'
本地起始-结束数组长度
如果[[$1==*:*];则

IFS=“:”read-r start end Cool。我查看了数组部分,但没有看到它。这太傻了,为什么它会出现在数组部分?*这也可以用于特殊变量
$@
${[@]:1:2}之类的数组吗
给出错误
错误替换
@Feuermurmel:不用索引方括号就可以了:
${:1:2}
@denniswillamson我发现我需要先将
$@
转换为正确的数组,否则包含空格的参数将被拆分:
ARGS=(“$@”);ARGS_之后的第一个=(“${ARGS[]:1}”)
这很好,但是需要注意的是,如果在函数中使用,它必须稍微修改为
“${$}[@]:1}”
@AlexGray:这给了我“糟糕的替换”,但是
${}:2}
工作正常。我正在搜索如何切掉数组的结尾,并被定向到这里。在这里找不到答案,这样做将是重复的,因为我在这里找到了答案。基本思想是,我们可以有一个算术表达式,如${数组[@]}-(2+7),其中长度在构造中是预期的${array:offset:length}。这里提供的答案都不能说明这一点。该死的家伙。道具。
array_slice() {
    local __doc__='
    Returns a slice of an array (similar to Python).

    From the Python documentation:
    One way to remember how slices work is to think of the indices as pointing
    between elements, with the left edge of the first character numbered 0.
    Then the right edge of the last element of an array of length n has
    index n, for example:
    ```
    +---+---+---+---+---+---+
    | 0 | 1 | 2 | 3 | 4 | 5 |
    +---+---+---+---+---+---+
    0   1   2   3   4   5   6
    -6  -5  -4  -3  -2  -1
    ```

    >>> local a=(0 1 2 3 4 5)
    >>> echo $(array.slice 1:-2 "${a[@]}")
    1 2 3
    >>> local a=(0 1 2 3 4 5)
    >>> echo $(array.slice 0:1 "${a[@]}")
    0
    >>> local a=(0 1 2 3 4 5)
    >>> [ -z "$(array.slice 1:1 "${a[@]}")" ] && echo empty
    empty
    >>> local a=(0 1 2 3 4 5)
    >>> [ -z "$(array.slice 2:1 "${a[@]}")" ] && echo empty
    empty
    >>> local a=(0 1 2 3 4 5)
    >>> [ -z "$(array.slice -2:-3 "${a[@]}")" ] && echo empty
    empty
    >>> [ -z "$(array.slice -2:-2 "${a[@]}")" ] && echo empty
    empty

    Slice indices have useful defaults; an omitted first index defaults to
    zero, an omitted second index defaults to the size of the string being
    sliced.
    >>> local a=(0 1 2 3 4 5)
    >>> # from the beginning to position 2 (excluded)
    >>> echo $(array.slice 0:2 "${a[@]}")
    >>> echo $(array.slice :2 "${a[@]}")
    0 1
    0 1

    >>> local a=(0 1 2 3 4 5)
    >>> # from position 3 (included) to the end
    >>> echo $(array.slice 3:"${#a[@]}" "${a[@]}")
    >>> echo $(array.slice 3: "${a[@]}")
    3 4 5
    3 4 5

    >>> local a=(0 1 2 3 4 5)
    >>> # from the second-last (included) to the end
    >>> echo $(array.slice -2:"${#a[@]}" "${a[@]}")
    >>> echo $(array.slice -2: "${a[@]}")
    4 5
    4 5

    >>> local a=(0 1 2 3 4 5)
    >>> echo $(array.slice -4:-2 "${a[@]}")
    2 3

    If no range is given, it works like normal array indices.
    >>> local a=(0 1 2 3 4 5)
    >>> echo $(array.slice -1 "${a[@]}")
    5
    >>> local a=(0 1 2 3 4 5)
    >>> echo $(array.slice -2 "${a[@]}")
    4
    >>> local a=(0 1 2 3 4 5)
    >>> echo $(array.slice 0 "${a[@]}")
    0
    >>> local a=(0 1 2 3 4 5)
    >>> echo $(array.slice 1 "${a[@]}")
    1
    >>> local a=(0 1 2 3 4 5)
    >>> array.slice 6 "${a[@]}"; echo $?
    1
    >>> local a=(0 1 2 3 4 5)
    >>> array.slice -7 "${a[@]}"; echo $?
    1
    '
    local start end array_length length
    if [[ $1 == *:* ]]; then
        IFS=":"; read -r start end <<<"$1"
        shift
        array_length="$#"
        # defaults
        [ -z "$end" ] && end=$array_length
        [ -z "$start" ] && start=0
        (( start < 0 )) && let "start=(( array_length + start ))"
        (( end < 0 )) && let "end=(( array_length + end ))"
    else
        start="$1"
        shift
        array_length="$#"
        (( start < 0 )) && let "start=(( array_length + start ))"
        let "end=(( start + 1 ))"
    fi
    let "length=(( end - start ))"
    (( start < 0 )) && return 1
    # check bounds
    (( length < 0 )) && return 1
    (( start < 0 )) && return 1
    (( start >= array_length )) && return 1
    # parameters start with $1, so add 1 to $start
    let "start=(( start + 1 ))"
    echo "${@: $start:$length}"
}
alias array.slice="array_slice"