问题描述
我会很短,我所拥有的是
array=( one.a two.b tree.c four.b five_b_abc)
我想要这个
array=( two.b four.b five_b_abc )
从here我找到了这个
# replace any array item matching "b*" with "foo"
array=( foo bar baz )
array=( "${array[@]/%b*/foo}" )
echo "${orig[@]}"$'
'"${array[@]}"
这怎么也不管用
array2=( ${array[@]//%^.p/})
结果array2=array
这将删除所有带有p的
array2=(${array[@]/*p*/})
结果array2=( one.a tree.c )
我需要知道如何添加^p(全部接受p),然后得到我的解决方案
array2=(${array[@]/*^p*/}
这是一个相当大的数组,大约10k个元素,我需要这样做,我需要尽可能快地处理数据,所以请不要使用循环解决方案。
推荐答案
编辑:添加了计时比较(结尾),删除了tr
可以使用bashParameter expansion替换数组元素的内容,即。${var[@]....}
但您无法实际删除元素。使用参数扩展所能得到的最好结果是将不需要的元素设为空("")。
相反,您可以使用printf
和sed
和IFS
。这样做的好处是允许您使用完整的正则表达式语法(不仅仅是外壳全局表达式)……而且它比使用循环快得多……
c
的数组元素
注意:此方法适用于数据中的空格。这是通过IFS=
实现的
IFS=$'
'; a=($(printf '%s
' "${a[@]}" |sed '/c/!d'))
这又是之前/之后转储:
#!/bin/bash
a=(one.ac two.b tree.c four.b "five b abcdefg" )
echo "======== Original array ===="
printf '%s
' "${a[@]}"
echo "======== Array containing only the matched elements 'c' ===="
IFS=$'
'; a=($(printf '%s
' "${a[@]}" |sed '/c/!d'))
printf '%s
' "${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=$'
'; a=($(printf '%s
' "${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