检查一个数组中的字符串是否在另一个数组中

Check if String from One Array in Other Array

我想要一个函数来报告两个数组中彼此相同的所有字符串。

ARRAY_A=("table" "dog" "bird" "caterpillar")
ARRAY_B=("cup" "door" "table" "cat")

for VALUE_B in "${ARRAY_B[@]}"
do
  [[ "${ARRAY_A[@]}" =~ ${VALUE_B} ]] && echo ${VALUE_B} is in both arrays

这 return 的输出:

table is in both arrays
cat is in both arrays

代码在 'caterpillar' 中查找 'cat' 并 returning 'cat is in both arrays'。如果两个数组中的字符串相同 ('cat':'cat').

,我只希望代码为 return 'cat is in both arrays'

虽然我可以添加一个嵌套的 for 循环来遍历并将 ARRAY_A 的每个值与 ARRAY_B 中的每个值进行比较,但这种解决方案在更大范围内效率低下。我相信有一个我还没有意识到的更有效的解决这个问题的方法。

此外,

我愿意接受一个解决方案,该解决方案检查 ARRAY_A 中是否有任何字符串以 ARRAY_B (bobcat:cat) 的值结尾。这让我尝试对上面的代码进行以下修改:

[[ "${ARRAY_A[@]}" =~ ${VALUE_B}$ ]] && echo $VALUE_B is in both arrays

但是,它只是将 ARRAY_B 的值与 ARRAY_A 的末尾作为一个整体进行比较,而不是 ARRAY_A 的各个值。同样,这可以通过嵌套 for 循环来解决,但我相信有更好的解决方案可以更有效地大规模工作。

While I could add in a nested for loop to go through and compare each value of ARRAY_A to each value in ARRAY_B

这样做。

this could be solved with a nested for loop

所以解决。

this solution would be inefficient on a larger scale

所提供的代码未正确处理元素中的空格,并且取决于 IFS 的值。简而言之,它是越野车。

也无法正确处理相互包含的元素,例如 A=(inside) B=(side)。常见的解决方案是在 [[ " ${ARRAY_A[*]} " =~ " $VALUE_B " ]].

前后添加空格

REGEX 匹配 =~ 在一个循环中多次分配内存用于存储 "${ARRAY_A[@]} 是昂贵的操作,“在更大的规模”将非常内存和 CPU 消耗.跟着rules of optimization不做,先剖析再做。

我认为双循环肯定会更清晰、更安全、bug 更少,对于“更大规模”甚至更快,因为 bash 不必解析 REGEX 也不必为元素的连接分配内存。这是要走的路。

(对于“更大规模”(就千兆字节数据而言)我首先不会使用 Bash 数组 - 我不想将整个数组存储在内存中。我会工作在文件上,使用 GNU 工具。假设元素将存储在文件中,我会 sort array1 > array1sorted; sort array2 > array2sorted; comm -12 array1sorted array2sorted)