检查文件是否包含在另一个文件中

时间:2014-12-10 08:53:27

标签: linux bash file

我有一个文件:a.txt,每行都有一个数字。我还有另一个文件b.txt,每行也有一个数字 如何检查文件a.txt中的所有行是否都包含在b.txt

7 个答案:

答案 0 :(得分:3)

您可以使用diff命令比较两个文件

使用示例

$ seq 1 5 > a.txt
$ seq 1 5 > b.txt
$ diff a.txt b.txt
$
$ seq 1 6 > b.txt
$ diff a.txt b.txt
5a6
> 6

修改

您也可以尝试类似

的内容
$ seq 1 5 > a.txt
$ seq 1 5 > b.txt
$ diff a.txt b.txt > /dev/null  && echo files are same || echo files are not same
files are same
$ seq 1 6 > b.txt
$ diff a.txt b.txt > /dev/null  && echo files are same || echo files are not same
files are not same

答案 1 :(得分:3)

您可以使用comm

如果a.txtb.txt已经排序(词汇和升序),您只需要

comm -23 a.txt b.txt

或者

comm -23 a.txt b.txt | wc -l

如果没有输出(或wc -l返回“0”),则a.txt中的每一行都在b.txt中(-2会抑制输出的行仅在b.txt中,-3会抑制两个文件中的行的输出。

如果文件未排序,您可以使用进程替换将每个文件的排序输出传递给comm

comm -23 <(sort a.txt) <(sort b.txt)

进程替换<(COMMAND)COMMAND的输出放入FIFO或/ dev / fd中的文件中(取决于系统支持的内容)。然后,命令行<(COMMAND)将替换为此文件的名称,作为命令行扩展的一部分。

这确实会检查行,因此如果a.txt中的数字存在两次,但b.txt中只存在一次,则会从a.txt输出重复行。如果您不关心重复项,请使用sort -u FILE代替sort FILE(或sort FILE | uniq,以防sort没有切换进行唯一排序)

答案 2 :(得分:1)

试试这个:

awk '
    NR==FNR{arr[$0]++;next}
    {print ($0 in arr) ? $0 " in both files" : $0 " *not* in both files"}
' b.txt a.txt

使用

 $ diff -a b.txt a.txt
2c2
< 3
---
> 2
6d5
< 7

答案 3 :(得分:1)

如果数字是唯一的(在每个文件中没有重复),你可以连接它们,然后通过管道排序然后unq并检查你有多少行。

例如:

>> cat a.txt
1
2
8
5
>> cat b.txt
1
2
5
3
8
>> cat a.txt b.txt | sort | uniq | wc -l
5

由于答案与b.txt中的行数相同,答案是肯定的!

答案 4 :(得分:0)

awk 'FNR==NR{b[$0];next}
            {if($0 in b){print $0" is present in b.txt"}
             else{print $0" is not present in b.txt"}
            }' b.txt a.txt

答案 5 :(得分:0)

Perl解决方案:

#!/usr/bin/perl
use strict;
use warnings;
use List::Compare;
#read file a.txt
open (my $fh, "<", "a.txt") or die $!;
while (<$fh>){
    push @atxt = $_;
}
close($fh); 
#read file b.txt
open (my $fh2, "<", "b.txt") or die $!;
while (<$fh2>){
    push @btxt = $_;
} 
close($fh2);

my $lc = List::Compare->new(\@atxt, \@btxt);

print $lc->get_intersection;
print $lc->get_union;
print $lc->get_unique;
print $lc->get_complement;

还有更多选项,请查看文档:{​​{3}}

答案 6 :(得分:0)

包含另一个文件的文件意味着a.txt的整个内容以相同的顺序出现在b.txt中,包括可能的重复,而你的最后一个问题是:

  

如何检查文件a.txt中的所有行是否都包含在b.txt?

意味着顺序和重复是无关紧要的。举个简单的例子:

a.txt:

5
7
3

b.txt:

9
5
3
7

满足您引用的问题,但不符合标题中的问题。

由于容器文件不是很庞大,解决引用的问题要容易得多(否则你会遇到像我下面演示的直接方法那样的内存问题)。一个简单的解决方案是创建一组包含在b.txt中的所有数字,然后遍历a.txt并返回false,以防在构造的集合中找不到项目。如果在完成迭代a.txt的内容时没有发生这种情况,那么返回true。

这在伪代码中如下所示:

ContentSet = {}
for each element b of b.txt
    add b into ContentSet

for each element a of a.txt
    if a is not in ContentSet then return false

return true

这种方法的优点是第一次迭代可以消除容器文件中可能的重复,从而将文件大小和搜索时间保持在最小,并且比给定的天真方法更快地运行第二次迭代该集合具有良好的散列实现,因为检查散列集是否包含给定对象是O(1)操作。