如何比较bash中的两个数组以查找所有相交的值?
让我们说:
array1包含值1和2
array2包含值2和3
我应该回来2。
我自己的答案,由于声誉不佳,我无法发帖:
for item1 in $array1; do
for item2 in $array2; do
if [[ $item1 = $item2 ]]; then
result=$result" "$item1
fi
done
done
我也在寻找替代解决方案。
答案 0 :(得分:17)
列表1的元素用作在list2中查找的正则表达式(表示为字符串:$ {list2 [*]}):
list1=( 1 2 3 4 6 7 8 9 10 11 12)
list2=( 1 2 3 5 6 8 9 11 )
l2=" ${list2[*]} " # add framing blanks
for item in ${list1[@]}; do
if [[ $l2 =~ " $item " ]] ; then # use $item as regexp
result+=($item)
fi
done
echo ${result[@]}
结果是
1 2 3 6 8 9 11
答案 1 :(得分:8)
采用@Raihan的答案并使其与非文件一起使用(虽然创建了FD) 我知道这有点像作弊,但似乎是不错的选择
副作用是输出数组将按字典顺序排序,希望没关系 (也不知道你有什么类型的数据,所以我只是用数字测试,如果你有特殊字符的字符串等可能需要额外的工作)
result=($(comm -12 <(for X in "${array1[@]}"; do echo "${X}"; done|sort) <(for X in "${array2[@]}"; do echo "${X}"; done|sort)))
测试:
$ array1=(1 17 33 99 109)
$ array2=(1 2 17 31 98 109)
result=($(comm -12 <(for X in "${array1[@]}"; do echo "${X}"; done|sort) <(for X in "${array2[@]}"; do echo "${X}"; done|sort)))
$ echo ${result[@]}
1 109 17
P.S。我确定有一种方法可以让数组在for
循环中每行输出一个值,我只是忘了它(IFS?)
答案 2 :(得分:3)
如果是两个文件(而不是数组),你正在寻找相交的行,你可以使用comm
命令。
$ comm -12 file1 file2
答案 3 :(得分:2)
您的回答无效,原因有两个:
$array1
只是扩展为array1
的第一个元素。 (至少,在我安装的Bash版本中,它是如何工作的。这似乎不是一个记录在案的行为,所以它可能是一个依赖于版本的怪癖。)result
后,result
将包含一个空格,因此result=$result" "$item1
的下一次运行会出现可怕的错误行为。 (而不是附加到result
,它将运行由前两项组成的命令,并将环境变量result
设置为空字符串。)更正:转动我错了这个:在分配中不会发生分词。 (见下面的评论。)你想要的是这个:
result=()
for item1 in "${array1[@]}"; do
for item2 in "${array2[@]}"; do
if [[ $item1 = $item2 ]]; then
result+=("$item1")
fi
done
done
答案 4 :(得分:0)
现在我理解你对“数组”的意思了,我认为 - 首先 - 你应该考虑使用实际的Bash数组。它们更灵活,因为(例如)数组元素可以包含空格,并且可以避免*
和?
触发文件名扩展的风险。
但是如果您更喜欢使用现有的以空格分隔的字符串方法,那么我同意RHT建议使用Perl:
result=$(perl -e 'my %array2 = map +($_ => 1), split /\s+/, $ARGV[1];
print join " ", grep $array2{$_}, split /\s+/, $ARGV[0]
' "$array1" "$array2")
(换行符只是为了便于阅读;如果你愿意,你可以摆脱它们。)
在上面的Bash命令中,嵌入式Perl程序创建一个名为%array2
的哈希,其中包含第二个数组的元素,然后它会打印%array2
中存在的第一个数组的所有元素。 / p>
这与你在第二个数组中处理重复值的代码的行为略有不同;在您的代码中,如果array1
包含x
两次且array2
包含x
三次,则result
将包含x
六次,而在我的代码result
只会包含x
两次。我不知道这是否重要,因为我不知道你的具体要求。