如何在Bash中对数组进行切片

Che*_*evy 171 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
   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 )"
}
Run Code Online (Sandbox Code Playgroud)

像这样使用:

$ A=( foo bar "a  b c" 42 )
$ slice B A 1 2
$ echo "${B[0]}"  # bar
$ echo "${B[1]}"  # a  b c
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?

Pau*_*ce. 269

请参阅Bash 页面中的Parameter Expansion部分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
Run Code Online (Sandbox Code Playgroud)

注意,保留"ab c"是一个数组元素(并且它包含额外空间)的事实.

  • 这是愚蠢的陈,为什么它会在阵列部分?*国资委 (25认同)
  • @Feuermurmel:只需要没有索引方括号:`$ {@:1:2}` (5认同)
  • @DennisWilliamson我发现我需要在执行此操作之前将`$ @`转换为正确的数组,否则包含空格的参数将被拆分:`ARGS =("$ @"); ARGS_AFTER_FIRST =("$ {ARGS [@]:1}")` (5认同)
  • @AquariusPower:创建一个索引数组并将其切片:`idx=(${!A[@]}); 回显${idx[@]:1}`。 (4认同)
  • 凉.我查看了Array部分,但没有在那里看到它. (2认同)
  • 这也可以用于类似数组的特殊变量`$@`吗?`${@[@]:1:2}` 给出了错误 `bad replacement`。 (2认同)

Nic*_*kin 45

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

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

  • 当你在它时:`echo"$ {A [@] :: 1}"#4` (8认同)
  • 这很好,但应该注意的是,如果在一个函数中使用它,必须稍微改变一下来读"$ {$ {@} [@]:1}"`. (7认同)