我有一个文件:a.txt
,每行都有一个数字。我还有另一个文件b.txt
,每行也有一个数字
如何检查文件a.txt
中的所有行是否都包含在b.txt
?
答案 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.txt
和b.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:
$ 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)操作。