编辑:添加了时间比较(最后)并去掉了tr
可以使用bash Parameter expansion替换数组元素的内容,即。 ${var[@]....} 但您实际上不能删除这些元素。使用参数扩展可以获得的最佳效果是使那些不需要的元素为 null ("")。
相反,您可以使用printf、sed 和IFS。这样做的好处是允许您使用完整的正则表达式语法(而不仅仅是 shell 通配表达式)......而且它比使用循环快 很多......
此示例留下包含 c 的数组元素
注意:此方法适用于数据中的空格。这是通过IFS=\n 实现的
IFS=$'\n'; a=($(printf '%s\n' "${a[@]}" |sed '/c/!d'))
这里又是之前/之后的转储:
#!/bin/bash
a=(one.ac two.b tree.c four.b "five b abcdefg" )
echo "======== Original array ===="
printf '%s\n' "${a[@]}"
echo "======== Array containing only the matched elements 'c' ===="
IFS=$'\n'; a=($(printf '%s\n' "${a[@]}" |sed '/c/!d'))
printf '%s\n' "${a[@]}"
echo "========"
输出:
======== Original array ====
one.ac
two.b
tree.c
four.b
five b abcdefg
======== Array containing only the matched elements 'c' ====
one.ac
tree.c
five b abcdefg
========
一般参考:测试包含 10k 个元素的数组。选择 5k:
a=( a\ \ \ \ b{0..9999} )
printf 方法采用:0m0.226s(产生顺序索引值)
第一种循环方法:0m4.007s(它会在索引值中留下空白)
第二种循环方式:0m7.862s(产生顺序索引值)
printf 方法:
IFS=$'\n'; a=($(printf '%s\n' "${a[@]}" |sed '/.*[5-9]...$/!d'))
第一个循环方法:
iz=${#a[@]}; j=0
for ((i=0; i<iz; i++)) ;do
[[ ! "${a[i]}" =~ .*[5-9]...$ ]] && unset a[$i]
done
第二个循环方法:
iz=${#a[@]}; j=0
for ((i=0; i<iz; i++)) ;do
if [[ ! "${a[i]}" =~ .*[5-9]...$ ]] ;then
unset a[$i]
else
a[$j]="${a[i]}=$i=$j"; ((j!=i)) && unset a[$i]; ((j+=1));
fi
done