nkv*_*nkv 4 arrays bash element conditional-statements
我会很简短,我拥有的是什么
array=( one.a two.b tree.c four.b five_b_abc)
Run Code Online (Sandbox Code Playgroud)
我要这个
array=( two.b four.b five_b_abc )
Run Code Online (Sandbox Code Playgroud)
从这里 我发现了这个
# replace any array item matching "b*" with "foo"
array=( foo bar baz )
array=( "${array[@]/%b*/foo}" )
echo "${orig[@]}"$'\n'"${array[@]}"
Run Code Online (Sandbox Code Playgroud)
怎么这不起作用
array2=( ${array[@]//%^.p/})
Run Code Online (Sandbox Code Playgroud)
结果 array2=array
这会删除所有p
array2=(${array[@]/*p*/})
Run Code Online (Sandbox Code Playgroud)
结果 array2=( one.a tree.c )
我需要一个想法如何添加^ p(所有接受p),并得到我的解决方案
array2=(${array[@]/*^p*/}
Run Code Online (Sandbox Code Playgroud)
它是一个相当大的数组,大约10k元素,我需要这样做,我需要它尽可能快地与数据,所以请不要循环解决方案.
编辑:添加时间比较(结束时)并摆脱了 tr
可以使用bash 参数扩展替换数组元素的内容,即.但你实际上不能删除元素.参数扩展可以获得的最好效果是使那些你不想要的元素为null(""). ${var[@]....}
相反,你可以使用printf和sed,和IFS.这有利于你使用完整的正则表达式语法(不仅仅是shell globbing表达式)...而且它比使用循环要快得多......
这个例子留下了包含的数组元素c
注意:这个方法适合数据中的空格.这是通过IFS=\n
IFS=$'\n'; a=($(printf '%s\n' "${a[@]}" |sed '/c/!d'))
Run Code Online (Sandbox Code Playgroud)
这里再次使用转储之前/之后:
#!/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 "========"
Run Code Online (Sandbox Code Playgroud)
输出:
======== 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
========
Run Code Online (Sandbox Code Playgroud)
供一般参考:测试包含10k元素的数组.选择5k:
a=( a\ \ \ \ b{0..9999} )
Run Code Online (Sandbox Code Playgroud)
printf方法采用:( 0m0.226s得到顺序索引值)
第一个循环方法:( 0m4.007s它在索引值中留下间隙)
第二个循环方法:( 0m7.862s得到顺序索引值)
printf方法:
IFS=$'\n'; a=($(printf '%s\n' "${a[@]}" |sed '/.*[5-9]...$/!d'))
Run Code Online (Sandbox Code Playgroud)
第一循环方法:
iz=${#a[@]}; j=0
for ((i=0; i<iz; i++)) ;do
[[ ! "${a[i]}" =~ .*[5-9]...$ ]] && unset a[$i]
done
Run Code Online (Sandbox Code Playgroud)
第二循环方法:
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
Run Code Online (Sandbox Code Playgroud)
您可以尝试以下方法:
array2=(`echo ${array[@]} | sed 's/ /\n/g' | grep b`)
Run Code Online (Sandbox Code Playgroud)