Bash中两个列表的交集

Bash中两个列表的交集,bash,Bash,我正在尝试编写一个简单的脚本,它将列出在两个列表中找到的内容。为了简化,让我们以ls为例。设想“一”和“二”是目录 one=`ls one` two=`ls two` intersection $one $two 一等于一` 二等于二` 1美元2美元 我对bash还很了解,所以请随意纠正我的做法。我只需要一些命令,将打印出所有文件在“一”和“二”。两者都必须存在。您可以将其称为“一”和“二”之间的“交叉点”。使用comm命令: ls one | sort > /tmp/one_list l

我正在尝试编写一个简单的脚本,它将列出在两个列表中找到的内容。为了简化,让我们以ls为例。设想“一”和“二”是目录

one=`ls one` two=`ls two` intersection $one $two 一等于一` 二等于二` 1美元2美元
我对bash还很了解,所以请随意纠正我的做法。我只需要一些命令,将打印出所有文件在“一”和“二”。两者都必须存在。您可以将其称为“一”和“二”之间的“交叉点”。

使用
comm
命令:

ls one | sort > /tmp/one_list
ls two | sort > /tmp/two_list
comm -12 /tmp/one_list /tmp/two_list
实际上并不需要“排序”,但我总是在使用“comm”之前加入它,以防万一。

comm-12一个效率较低(比comm)的替代方案:

comm -12  <(ls 1) <(ls 2)
cat <(ls 1 | sort -u) <(ls 2 | sort -u) | uniq -d

cat使用
comm的解决方案

comm
很棒,但确实需要使用排序列表。幸运的是,这里我们使用了
ls
,它来自
ls
Bash手册页

如果没有-cftuSUX或--Sort,则按字母顺序对条目进行排序


comm-12Join是另一个很好的选择,这取决于输入和所需的输出

join -j1 -a1 <(ls 1) <(ls 2)

join-j1-a1还有另一个Stackoverflow问题“bash中的数组交集”,它被标记为此问题的副本。在我看来,这并不完全相同,因为这个问题讨论的是比较两个bash数组,而这个问题的重点是bash文件。对另一个问题的一行答复(现已结束)如下:

# List1=( 0 1 2 3 4   6 7 8 9 10 11 12)
# List2=(   1 2 3   5 6   8 9    11 )
# List3=($(comm -12 <(echo ${List1[*]}| tr " " "\n"| sort) <(echo ${List2[*]} | tr " " "\n"| sort)| sort -g))
# echo ${List3[*]}
1 2 3 6 8 9 11
#列表1=(01 2 3 4 6 7 8 9 10 11 12)
#列表2=(123568911)

#List3=($(comm-12很好包含它,因为它确实需要排序,他只使用ls作为示例。真不敢相信直到今天我才知道
comm
。这让我整整一周:)
comm
要求对输入进行排序。在这种情况下,
ls
会自动对其输出进行排序,但其他用途可能需要这样做:
comm-12对任何内容都不使用ls的输出。ls是一个交互式查看目录元数据的工具。任何试图用代码解析ls的输出的尝试都会被破坏。Globs更简单D对于*.txt“”中的文件,更正为:“”。读取我刚才使用此命令是为了查找
public
方法
error()的用法
由trait提供,与
git grep
相结合,真是太棒了!我运行了
$comm-12这太搞笑了。我正试图用awk做一些疯狂的事情。这里没有任何东西真正回答这个问题:如何在Bash脚本中使两个变量相交。在我看来,这是一个新问题,这个问题清楚地回答了她e、 一种可能更有用的方法是近乎重复的方法。如果在脚本中使用Debian的/bin/dash或其他非Bash shell,则可以使用括号链接命令的输出:
(ls 1;ls 2)| sort-u | uniq-d
@MikaëlMayer你应该标记你要回复的人的名字,否则就假定你指的是我。@nikaëlMayer是正确的-链接
sort-u | uniq-d
什么都不做,因为排序在uniq开始查找之前已经删除了重复项。我想你还不明白我的意思命令正在执行。@Benubird我无法获取您的命令
cat@non我之所以使用cat,是因为我希望这是一个可推广的解决方案,以便您可以用其他内容替换
ls
。例如
find
。您的解决方案不允许这样做,因为如果其中一个命令返回两行相同的内容,它将被删除将其作为副本拾取。即使用户希望执行
ls 1/*
并比较子目录中的所有文件,我的也可以工作。否则,是的,它也可以工作。我的可能是特定于bash的。我认为这通常称为对称差异,而不是补码。
cd $(mktemp -d) && mkdir {one,two} && touch {one,two}/file_{1,2}{0..9} && touch two/file_3{0..9}
join -j1 -a1 <(ls 1) <(ls 2)
# List1=( 0 1 2 3 4   6 7 8 9 10 11 12)
# List2=(   1 2 3   5 6   8 9    11 )
# List3=($(comm -12 <(echo ${List1[*]}| tr " " "\n"| sort) <(echo ${List2[*]} | tr " " "\n"| sort)| sort -g))
# echo ${List3[*]}
1 2 3 6 8 9 11