如何在 Bash 中对数组进行切片
查看 bash(1) 手册页中的“数组”部分,我没有找到对数组进行切片的方法。
所以我想出了这个过于复杂的函数:
#!/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
有更好的方法吗?
Looking the "Array" section in the bash(1) man page, I didn't find a way to slice an array.
So I came up with this overly complicated function:
#!/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=
Used like this:
$ A=( foo bar "a b c" 42 )
$ slice B A 1 2
$ echo "${B[0]}" # bar
$ echo "${B[1]}" # a b c
Is there a better way to do this?
\n'
eval $output="( \$tmp )"
}
Used like this:
Is there a better way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
请参阅 Bash 中的参数扩展部分<代码>手册页。
A[@]
返回数组的内容,:1:2
采用长度为 2 的切片,从索引 1 开始。请注意,
ab c
是一个数组元素(并且它包含一个额外的空间)被保留。See the Parameter Expansion section in the Bash
man
page.A[@]
returns the contents of the array,:1:2
takes a slice of length 2, starting at index 1.Note that the fact that
a b c
is one array element (and that it contains an extra space) is preserved.还有一个方便的快捷方式可以获取以指定索引开头的数组的所有元素。例如,“${A[@]:1}”将是数组的“尾部”,即没有第一个元素的数组。
There is also a convenient shortcut to get all elements of the array starting with specified index. For example "${A[@]:1}" would be the "tail" of the array, that is the array without its first element.
像 Python 中一样的数组切片(来自 rebash 库):
Array slicing like in Python (From the rebash library):
冒着死马的风险,我受到了 @ 的启发jandob 的答案 并使这个版本更
shift
逻辑或经常重写变量)。IFS
(仅限-r
模式)。-l
标志指定[start, end)
切片或[start, length]
切片。回显
结果数组(默认行为),或将其“返回”到一个新数组以供调用父级使用(通过-r slicedArray
)。注意: namerefs 仅在 Bash 中受支持 > = 4.3。要支持早期版本的 Bash(即没有 Brew bash 的 Mac),您需要使用 间接:使用临时变量来访问数组参数,例如
declare arrValuesCmd="$1[@]";声明 arr=("${!arrValuesCmd}")
,并使用 eval 作为返回值,例如eval $retArrName='("${newArr[@]}")'
(请注意数组声明周围的单引号)。示例:
At the risk of beating a dead horse, I was inspired by @jandob's answer and made this version that
shift
logic or rewriting of variables as often).IFS
(-r
mode only).[start, end)
slicing or[start, length]
slicing via-l
flag.echo
the resulting array (default behavior), or "return" it into a new array for use in the calling parent (via-r slicedArray
).Note: namerefs are only supported in Bash >= 4.3. To support earlier versions of Bash (i.e. Mac without Brew's bash), you'll need to use indirection instead: use a temp var to access array parameters, e.g.
declare arrValuesCmd="$1[@]"; declare arr=("${!arrValuesCmd}")
, and use eval for return values, e.g.eval $retArrName='("${newArr[@]}")'
(note the single quotes around the array declaration).Examples: