我想使用数组上的bash参数展开来包含匹配给定模式的项,而不是排除它们。
下面是一个排除匹配ba*的项的示例
ar=( foo bar baz qux )
for i in ${ar[@]##ba*}; do
echo "$i"
done
# foo
# qux这一切都很好,但在本例中,我实际上只想包括与ba*匹配的项。
下面是我尝试过的,坦白地说,我不太清楚如何解释结果:
ar=( foo bar baz qux )
#shopt -s extglob # seems to have no effect either way
for i in ${ar[@]##!(ba*)}; do
echo "$i"
done
# ar
# az看起来我在这种情况下,我得到了正确的项目,但他们的价值已经被咀嚼。
以下是我目前的工作解决方案:
ar=( foo bar baz qux )
for i in ${ar[@]}; do
if [[ "$i" =~ ba* ]]; then
echo "$i"
fi
done
# bar
# baz我正在使用Mac,并且已经在Mac捆绑bash 3.2.51以及安装了bash 4.2.45的国产操作系统上进行了测试。
谢谢!
编辑
@casc (正确)建议在下面重新添加从火柴中删除的'b‘,但这不是我想要的。
我的实际用例更像是包含与*ba*匹配的项,而不仅仅是ba*。关键是我不一定知道完整的字符串,只是它肯定会有模式ba*在某个地方。这可能是一个更好的例子:
ar=( foo zoobar waybaz qux )
for i in ${ar[@]}; do
if [[ "$i" =~ ba* ]]; then
# do something with $i
fi
done
# zoobar
# waybaz发布于 2013-12-31 17:28:34
从数组的每个元素中,删除与ba*不匹配的最长前缀。
foo和qua,整个字符串不匹配。bar和baz,b与ba*不匹配,但ba匹配,因此只有b被删除。发布于 2014-01-27 12:43:08
为什么不简单地把切断后的b再做一次呢?
(
shopt -s extglob
ar=( foo bar baz qux )
for i in ${ar[@]/#!(ba*)}; do
echo "b${i}"
done
)
# ... or ...
(
export IFS=""
ar=( foo bar baz qux )
ar=( ${ar[@]/#!(ba*)} )
ar=( ${ar[@]/#/b} )
echo ${!ar[*]}
printf '%s\n' "${ar[@]}"
)其他备选办法包括:
ar=( foo bar baz qux )
printf '%s\n' "${ar[@]}" "${ar[@]##ba*}" | sort | uniq -u
printf '%s\n' "${ar[@]}" "${ar[@]/#ba*}" | sort | uniq -u
# alternative to current working solution
(
array=( foo bar baz qux )
for item in "${ar[@]}"; do
case "$item" in
ba*) echo "$item";;
*) :;;
esac
done
)https://stackoverflow.com/questions/20860850
复制相似问题