Bash中两个数组的比较/差异 [英] Compare/Difference of two arrays in Bash

查看:49
本文介绍了Bash中两个数组的比较/差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Bash 中能否取两个数组的差值.有什么好的方法可以做到?

代码:

Array1=(key1"key2"key3"key4"key5"key6"key7"key8"key9"key10")Array2=(key1"key2"key3"key4"key5"key6")Array3 =diff(Array1, Array2)Array3 理想情况下应该是:Array3=(key7"key8"key9"key10")

解决方案

如果你严格想要Array1 - Array2,那么

Array1=( "key1" "key2" "key3" "key4" "key5" "key6" "key7" "key8" "key9" "key10" )Array2=( "key1" "key2" "key3" "key4" "key5" "key6" )数组 3=()对于我在${Array1[@]}"中;做跳过=对于${Array2[@]}"中的 j;做[[ $i == $j ]] &&{跳过=1;休息;}完毕[[ -n $skip ]] ||Array3+=("$i")完毕声明 -p Array3

使用关联数组可能会改进运行时,但我个人不会打扰.如果您处理的数据足够重要,那么 shell 是错误的工具.

<小时>

对于像丹尼斯的答案这样的对称差异,现有的工具如 comm 工作,只要我们稍微调整输入和输出(因为它们适用于基于行的文件,而不是 shell 变量).

在这里,我们告诉 shell 使用换行符将数组连接成单个字符串,并在从 comm 读回数组时丢弃制表符.

<前>$ oldIFS=$IFS IFS=$'\n\t'$ Array3=($(comm -3 <(echo "${Array1[*]}") <(echo "${Array2[*]}")))通讯:文件 1 未按顺序排列$ IFS=$oldIFS$ 声明 -p Array3声明 -a Array3='([0]="key7" [1]="key8" [2]="key9" [3]="key10")'

它抱怨是因为,通过字典排序,key1 <;... <键 9 >key10.但由于两个输入数组的排序方式相似,因此可以忽略该警告.您可以使用 --nocheck-order 来消除警告,或者添加一个 |如果不能保证输入数组的顺序和唯一性,请在 <(…) 过程替换中使用 sort -u.

Is it possible to take the difference of two arrays in Bash. What is a good way to do it?

Code:

Array1=( "key1" "key2" "key3" "key4" "key5" "key6" "key7" "key8" "key9" "key10" )
Array2=( "key1" "key2" "key3" "key4" "key5" "key6" ) 

Array3 =diff(Array1, Array2)

Array3 ideally should be :
Array3=( "key7" "key8" "key9" "key10" )

解决方案

If you strictly want Array1 - Array2, then

Array1=( "key1" "key2" "key3" "key4" "key5" "key6" "key7" "key8" "key9" "key10" )
Array2=( "key1" "key2" "key3" "key4" "key5" "key6" )

Array3=()
for i in "${Array1[@]}"; do
    skip=
    for j in "${Array2[@]}"; do
        [[ $i == $j ]] && { skip=1; break; }
    done
    [[ -n $skip ]] || Array3+=("$i")
done
declare -p Array3

Runtime might be improved with associative arrays, but I personally wouldn't bother. If you're manipulating enough data for that to matter, shell is the wrong tool.


For a symmetric difference like Dennis's answer, existing tools like comm work, as long as we massage the input and output a bit (since they work on line-based files, not shell variables).

Here, we tell the shell to use newlines to join the array into a single string, and discard tabs when reading lines from comm back into an array.

$ oldIFS=$IFS IFS=$'\n\t'
$ Array3=($(comm -3 <(echo "${Array1[*]}") <(echo "${Array2[*]}")))
comm: file 1 is not in sorted order
$ IFS=$oldIFS
$ declare -p Array3
declare -a Array3='([0]="key7" [1]="key8" [2]="key9" [3]="key10")'

It complains because, by lexographical sorting, key1 < … < key9 > key10. But since both input arrays are sorted similarly, it's fine to ignore that warning. You can use --nocheck-order to get rid of the warning, or add a | sort -u inside the <(…) process substitution if you can't guarantee order&uniqueness of the input arrays.

这篇关于Bash中两个数组的比较/差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆