簡體   English   中英

減去 2 個字符串 arrays 時的奇怪行為

[英]Strange behaviour while subtracting 2 string arrays

我從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)

我減去它們的方式是

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

echo ${array1[@]}

現在我的預期結果應該是

dev-monitoring-busk test-ci-cd

但我的預期結果是

dev--busk test-ci-cd

雖然減法看起來不錯,但它也從dev-monitoring-busk中刪除了字符串monitoring 我不明白為什么。 有人可以指出這里有什么問題嗎?

我知道還有其他解決方案可以解決 2 個 arrays 之間的差異,例如

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

但這更多的是差異而不是減法。 所以這對我不起作用。

有點雜亂無章,但它的工作...

  • 使用comm查找對(排序的)數據集唯一的項目
  • 使用tr在空格(' ' == 數組元素分隔符)和回車('\n'; comm在單獨的行上工作)之間進行轉換
  • echo "${array1[@]}" | tr ' ' '\n' | sort echo "${array1[@]}" | tr ' ' '\n' | sort :將數組的元素轉換為單獨的行並排序
  • comm -23 (sorted data set #1) (sorted data set #2) : 比較已排序的數據集並返回只存在於數據集 #1 中的行

把這一切放在一起給我們:

$ 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

關於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)

如果我理解正確,您想要的不是從array2中減去array1 ,而是從array1中減去array2 正如其他人指出的那樣, bash替換不適用於 arrays。 相反,如果您的 bash 版本 >= 4.2,您可以使用associative array

請嘗試以下方法:

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並使用關聯數組mark標記其元素。
  • 然后它遍歷array1並將元素添加到answer中,如果它在mark中沒有看到。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM