如何解决Bash-在数组元素上进行整个字符串匹配的最快方法?
我有bash数组(以下称为tenantlist_array
),其中填充了以下格式的元素:
{3 characters}-{3-5 characters}{3-5 digits}-{2 chars}{1-2 digits}
。
示例:
abc-hac101-bb0
xyz-b2blo97250-aa99
abc-b2b9912-xy00
fff-hac101-g3
数组元素是唯一的。请注意连字符,它是每个数组元素的一部分。
我需要检查提供的字符串(在下面的示例中用作变量tenant
)是否与任何数组元素都完全匹配-因为数组元素是唯一的,所以第一个匹配就足够了。
我正在使用简单的代码遍历数组元素:
tenant="$1"
for k in "${tenantlist_array[@]}"; do
result=$(grep -x -- "$tenant" <<<"$k")
if [[ $result ]]; then
break
fi
done
请注意-我需要一个完整的字符串匹配-例如,如果我搜索的字符串是hac101
,它一定不匹配任何数组元素,即使可以是如果是数组元素,则为子字符串。
换句话说,只有完整字符串abc-hac101-bb0
必须与第一个元素产生匹配项。字符串abc
,abc-hac
,b2b
,99
,-
不能产生匹配。这就是-x
参数与grep调用一起使用的原因。
现在,上面的代码有效,但是我发现它很慢。我已经使用具有193个元素的数组来运行它,并且在普通笔记本上花了将近90秒的时间来遍历数组元素:
real 1m2.541s
user 0m0.500s
sys 0m24.063s
随着数组中的385个元素,时间如下:
real 2m8.618s
user 0m0.906s
sys 0m48.094s
所以我的问题-有更快的方法吗?
解决方法
在不运行任何循环的情况下,您可以使用glob:
tenant="$1"
[[ $(printf '\3%s\3' "${tenantlist_array[@]}") == *$'\3'"$tenant"$'\3'* ]] &&
echo "ok" || echo "no"
在printf
中,我们在每个元素周围放置一个控制字符\3
,并在进行比较时确保将\3
放在搜索键之前和之后。
感谢 @ arco444 ,该解决方案非常简单:
tenant="$1"
for k in "${tenantlist_array[@]}"; do
if [[ $k = "$tenant" ]]; then
result="$k"
break
fi
done
和385个成员数组的种子差异:
real 0m0.007s
user 0m0.000s
sys 0m0.000s
快数千倍 。
这给出了调用grep有多浪费的想法,如果可能的话,应该避免这种情况。
,这是另一种使用grep
的方式,实际上实际上是在尽最大可能使用grep
。
首次创建数组时,只需在每个uuid字符串的末尾附加一个\n
,即可完全删除“格式化”数组的代码。
随着所比较的字符串的长度和数组的长度,此代码的降级速度也会慢得多。
tenant="$1"
formatted_array=""
for k in "${tenantlist_array[@]}"; do
formatted_array="$formatted_array $i\n"
done
result=$(echo -e "$formatted_array" | grep $tenant)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。