找出 array2 中缺少 array1 的哪些值
Find out what values of `array1` are missing in `array2`
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 )
使用 mapfile
、comm
、sort
和进程替换:
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 "%s\n" "${array1[@]}" | sort -n) \
<(printf "%s\n" "${array2[@]}" | sort -n))
结果:
$ declare -p arr
declare -a arr='([0]="4" [1]="8")'
解释,由内而外:
每行打印数组一个元素并排序:
$ printf "%s\n" "${array1[@]}" | sort -n
1
2
3
4
5
6
7
8
9
10
11
12
array2
.
也一样
将这些管道包装到进程替换中,并将它们用作 comm
:
的参数
comm -23 --nocheck-order \
<(printf "%s\n" "${array1[@]}" | sort -n) \
<(printf "%s\n" "${array2[@]}" | sort -n)
-23
将结果缩减为第一个数组唯一的值; --nocheck-order
禁止显示有关输入未按字典顺序排序的警告。这个的输出是
4
8
用 mapfile
将每一行读入数组元素(-t
删除换行符):
mapfile -t arr < <(comm -23 --nocheck-order \
<(printf "%s\n" "${array1[@]}" | sort -n) \
<(printf "%s\n" "${array2[@]}" | sort -n))
现在,arr
包含如上所示的两个值。
sort
步骤不是严格要求的,但也使解决方案适用于未排序的数组。
下面的在线人会做这个把戏:
diff -y <(printf '%s\n' "${array2[@]}") <(printf '%s\n' "${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 '%s\n' "${arrayN[@]}"|sort -n)
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 )
使用 mapfile
、comm
、sort
和进程替换:
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 "%s\n" "${array1[@]}" | sort -n) \
<(printf "%s\n" "${array2[@]}" | sort -n))
结果:
$ declare -p arr
declare -a arr='([0]="4" [1]="8")'
解释,由内而外:
每行打印数组一个元素并排序:
$ printf "%s\n" "${array1[@]}" | sort -n 1 2 3 4 5 6 7 8 9 10 11 12
array2
. 也一样
将这些管道包装到进程替换中,并将它们用作
的参数comm
:comm -23 --nocheck-order \ <(printf "%s\n" "${array1[@]}" | sort -n) \ <(printf "%s\n" "${array2[@]}" | sort -n)
-23
将结果缩减为第一个数组唯一的值;--nocheck-order
禁止显示有关输入未按字典顺序排序的警告。这个的输出是4 8
用
mapfile
将每一行读入数组元素(-t
删除换行符):mapfile -t arr < <(comm -23 --nocheck-order \ <(printf "%s\n" "${array1[@]}" | sort -n) \ <(printf "%s\n" "${array2[@]}" | sort -n))
现在,
arr
包含如上所示的两个值。
sort
步骤不是严格要求的,但也使解决方案适用于未排序的数组。
下面的在线人会做这个把戏:
diff -y <(printf '%s\n' "${array2[@]}") <(printf '%s\n' "${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 '%s\n' "${arrayN[@]}"|sort -n)