简体   繁体   English

减去 2 个字符串 arrays 时的奇怪行为

[英]Strange behaviour while subtracting 2 string arrays

I am subtracting array1 from array2 My 2 arrays are我从array2中减去array1我的 2 arrays 是

array1=(apps argocd cache core dev-monitoring-busk test-ci-cd)
array2=(apps argocd cache core default kube-system kube-public kube-node-lease monitoring)

And the way Im subtracting them is我减去它们的方式是

for i in "${array2[@]}"; do
         array1=(${array1[@]//$i})
done

echo ${array1[@]}

Now my expected result should be现在我的预期结果应该是

dev-monitoring-busk test-ci-cd

But my expected result is但我的预期结果是

dev--busk test-ci-cd

Although the subtraction looks good but its also deleting the string monitoring from dev-monitoring-busk .虽然减法看起来不错,但它也从dev-monitoring-busk中删除了字符串monitoring I dont understand why.我不明白为什么。 Can some point out whats wrong here?有人可以指出这里有什么问题吗?

I know that there are other solutions out there for a diff between 2 arrays like我知道还有其他解决方案可以解决 2 个 arrays 之间的差异,例如

echo ${Array1[@]} ${Array2[@]} | tr ' ' '\n' | sort | uniq -u

But this is more of a diff and not a subtraction.但这更多的是差异而不是减法。 So this does not work for me.所以这对我不起作用。

Bit of a kludge but it works...有点杂乱无章,但它的工作...

  • use comm to find those items unique to a (sorted) data set使用comm查找对(排序的)数据集唯一的项目
  • use tr to convert between spaces (' ' == array element separator) and carriage returns ('\n'; comm works on individual lines)使用tr在空格(' ' == 数组元素分隔符)和回车('\n'; comm在单独的行上工作)之间进行转换
  • echo "${array1[@]}" | tr ' ' '\n' | sort echo "${array1[@]}" | tr ' ' '\n' | sort : convert an array's elements into separate lines and sort echo "${array1[@]}" | tr ' ' '\n' | sort :将数组的元素转换为单独的行并排序
  • comm -23 (sorted data set #1) (sorted data set #2) : compare sorted data sets and return the rows that only exist in data set #1 comm -23 (sorted data set #1) (sorted data set #2) : 比较已排序的数据集并返回只存在于数据集 #1 中的行

Pulling this all together gives us:把这一切放在一起给我们:

$ array1=(apps argocd cache core dev-monitoring-busk test-ci-cd)
$ array2=(apps argocd cache core default kube-system kube-public kube-node-lease monitoring)

# find rows that only exist in array1

$ comm -23 <(echo "${array1[@]}" | tr ' ' '\n' | sort) <(echo "${array2[@]}" | tr ' ' '\n' | sort)
dev-monitoring-busk
test-ci-cd

# same thing but this time replace carriage returns with spaces (ie, pull all items onto a single line of output):

$ comm -23 <(echo "${array1[@]}" | tr ' ' '\n' | sort) <(echo "${array2[@]}" | tr ' ' '\n' | sort) | tr '\n' ' '
dev-monitoring-busk test-ci-cd

NOTEs about comm :关于comm的注意事项:

- takes 2 sorted data sets as input
- generates 3 columns of output:
    - (output column #1) rows only in data set #1
    - (output column #2) rows only in data set #2
    - (output column #3) rows in both data sets #1 and #2
- `comm -xy` ==> discard ouput columns 'x' and 'y'
    - `comm -12` => discard output columns #1 and #2 => only show lines common to both data sets (output column #3)
    - `comm -23' => discard output columns #2 and #3 => only show lines that exist in data set #1 (output column #1)

If I'm understanding correctly, what you want is not to subtract array1 from array2 , but to subtract array2 from array1 .如果我理解正确,您想要的不是从array2中减去array1 ,而是从array1中减去array2 As others are pointing out, bash replacement do not work with arrays.正如其他人指出的那样, bash替换不适用于 arrays。 Instead you can make use of an associative array if your bash version >= 4.2.相反,如果您的 bash 版本 >= 4.2,您可以使用associative array

Please try the following:请尝试以下方法:

declare -a array1=(apps argocd cache core dev-monitoring-busk test-ci-cd)
declare -a array2=(apps argocd cache core default kube-system kube-public kube-node-lease monitoring)

declare -A mark
declare -a ans

for e in "${array2[@]}"; do
    mark[$e]=1
done

for e in "${array1[@]}"; do
    [[ ${mark[$e]} ]] || ans+=( "$e" )
done

echo "${ans[@]}"
  • It first iterate over array2 and marks its elements by using an associative arrray mark .它首先遍历array2并使用关联数组mark标记其元素。
  • It then iterates over array1 and add the element to the answer if it is not seen in the mark .然后它遍历array1并将元素添加到answer中,如果它在mark中没有看到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM