找出“array2”中缺少“array1”的哪些值


declare -a array1=( 1 2 3 4 5 6 7 8 9 10 11 12 )
declare -a array2=( 1 2 3 5 6 7 9 10 11 12 )

在 bash 中,如何获取array1中存在但在array2中不存在的值的第三个数组?在上面的示例中,预期输出为( 4 8 )

使用 mapfilecommsort 和 process 替换:

array1=( 1 2 3 4 5 6 7 8 9 10 11 12 )
array2=( 1 2 3 5 6 7 9 10 11 12 )
mapfile -t arr < <(comm -23 --nocheck-order 
                       <(printf "%sn" "${array1[@]}" | sort -n) 
                       <(printf "%sn" "${array2[@]}" | sort -n))

结果:

$ declare -p arr
declare -a arr='([0]="4" [1]="8")'

解释,由内而外:

  • 每行打印一个元素的数组并排序:

    $ printf "%sn" "${array1[@]}" | sort -n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    

    array2也是如此.

  • 将这些管道包装到进程替换中,并将它们用作comm的参数:

    comm -23 --nocheck-order 
        <(printf "%sn" "${array1[@]}" | sort -n) 
        <(printf "%sn" "${array2[@]}" | sort -n)
    

    -23将结果简化为第一个数组唯一的值; --nocheck-order禁止显示有关输入未按字典顺序排序的警告。其输出为

    4
    8
    
  • 使用mapfile将每一行读入数组元素(-t删除换行符):

    mapfile -t arr < <(comm -23 --nocheck-order 
                       <(printf "%sn" "${array1[@]}" | sort -n) 
                       <(printf "%sn" "${array2[@]}" | sort -n))
    

    现在,arr包含如上所示的两个值。

sort步骤不是严格要求的,但使解决方案也适用于未排序的数组。

以下在线者将做到这一点:

diff -y <(printf '%sn' "${array2[@]}") <(printf '%sn' "${array1[@]}") | grep -Po '[|<>][t]K[0-9]+$'

printf用于在单独的行中打印元素。现在diff -y给出输出:

1           1    
2           2
3           3
5         | 4
6           5
7           6   
9           7
10        | 8
11          9
12          10
            11
            12

现在,您只需过滤|(有时<>)之后的数字。我为此使用了grep,但也可以使用sed。如果您的数组未排序,只需像这样为每个printf添加排序:

(printf '%sn' "${arrayN[@]}"|sort -n)

相关内容

  • 没有找到相关文章

最新更新