bash中的数组交集

dab*_*st1 16 bash

你如何比较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
Run Code Online (Sandbox Code Playgroud)

我也在寻找替代解决方案.

Fri*_*ner 19

列表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[@]}
Run Code Online (Sandbox Code Playgroud)

结果是

1 2 3 6 8 9 11
Run Code Online (Sandbox Code Playgroud)


nhe*_*hed 8

采用@Raihan的答案并使其与非文件一起工作(虽然创建了FD)我知道这有点像作弊但似乎是一个很好的选择

副作用是输出数组将按字典顺序排序,希望没关系(也不知道你有什么类型的数据,所以我只是用数字测试,如果你有特殊字符的字符串等可能需要额外的工作)

result=($(comm -12 <(for X in "${array1[@]}"; do echo "${X}"; done|sort)  <(for X in "${array2[@]}"; do echo "${X}"; done|sort)))
Run Code Online (Sandbox Code Playgroud)

测试:

$ 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
Run Code Online (Sandbox Code Playgroud)

ps我确定有一种方法可以让数组在for循环中每行输出一个值,我只是忘了它(IFS?)

  • `printf - '%s \n'"$ {array [@]}"`将在单独的行上输出每个元素. (4认同)

rua*_*akh 5

你的答案不会起作用,原因有二:

  • $array1只是扩展到 的第一个元素array1。(至少,在我安装的 Bash 版本中,它是这样工作的。这似乎没有记录在案的行为,所以它可能是一个依赖于版本的怪癖。)
  • 第一个元素添加到 后resultresult将包含一个空格,因此下一次运行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
Run Code Online (Sandbox Code Playgroud)