我有一个文件:a.txt
,每行都有一个数字。我还有另一个文件b.txt
,每行也有一个数字。
如何检查文件a.txt
的所有行是否都包含在b.txt
中?
我有一个文件:a.txt
,每行都有一个数字。我还有另一个文件b.txt
,每行也有一个数字。
如何检查文件a.txt
的所有行是否都包含在b.txt
中?
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
没有唯一排序开关的情况下使用sort FILE | uniq
)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
Try this :
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
>> 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
中的行数相同,所以答案是肯定的!
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
#!/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;
还有许多其他选项,请查看文档:http://search.cpan.org/~jkeenan/List-Compare-0.39/lib/List/Compare.pm
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)操作。