[英]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...有点杂乱无章,但它的工作...
comm
to find those items unique to a (sorted) data setcomm
查找对(排序的)数据集唯一的项目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[@]}"
array2
and marks its elements by using an associative arrray mark
.array2
并使用关联数组mark
标记其元素。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.