我怎样才能获取第一个文件中包含的非 i 的名称?

我怎样才能获取第一个文件中包含的非 i 的名称?

我有两个包含数十亿个 DNA 序列名称的文件,第二个文件是第一个文件的真子集:

例如,

1°:john mike anna paul laura .... 

2°:john mike paul ...

所有名字都占据一行。

我的问题是,如何获取第一个文件中包含但不在第二个文件中的名称?

谢谢大家!

答案1

这很简单,但如果每行只有一个名称,而不是用空格分隔列表,您的生活会轻松得多。Linux 中有许多出色的实用程序可用于处理文本文件,这是所有 *nix 都擅长的事情之一,但大多数都希望每行只有一个项目。因此,我的大多数解决方案都将从相应地修改文件开始。

将您的文件更改为每行一个名称:

sed 's/ /\n/g' file > newfile

或者修改原始文件

sed -i 's/ /\n/g' file

一旦你完成了这些,以下任何一个都会给你你想要的东西:

  1. grep

    $ grep -vFwf file2 file1
    anna
    laura
    
  2. comm或者diff

    $ comm -23 <(sort file1) <(sort file2)
    anna
    laura
    
    
    $ diff file1 file2 | grep -Po '<\s+\K.*'
    anna
    laura
    
  3. awk

    $ awk '(NR==FNR){a[$1]++; next}!($1 in a){print}' file2 file1 
    laura
    anna
    
  4. Perl

    $ perl -lne 'BEGIN{open(A,"file2"); while(<A>){chomp; $k{$_}++}} print unless $k{$_}' file2 file1
    laura
    anna
    

    或者

    $ perl -lne '$k{$_}++; END{map{print unless $k{$_}>1}keys(%k)}' file2 file1
    laura
    anna
    

如果你真的不想改变文件的格式(但你确实应该这么做),你可以这样做

awk '{for (i=1;i<=NF;i++){a[$i]++}}END{for(n in a){if(a[n]<2){print n}}}' file2 file1

或者

perl -lane '$k{$_}++ for @F; END{map{print if $k{$_}<2} keys(%k)}' file1 file2

答案2

如果它们按换行符排序和分隔,则您可以使用它来comm显示 file1 所特有的行:

comm -23 file1 file2

演示:

$ comm -23 <(echo -e 'john\nmike\nanna\npaul\nlaura'|sort) <(echo -e 'john\nmike\npaul'|sort)
anna
laura

或者你可以diff做同样的事情(grep正在寻找行删除):

diff sorted-file-1 sorted-file-2 | grep -oP '(?<=< ).+'

如果您需要避免排序或处理大量数字,我建议您使用适当的语言进行基于字典的查找。简单的 Python 示例:

file2 = {}
with open("file2") as f:
    for line in f:
        file2[line] = 0

with open("file1") as f:
    for line in f:
        if not line in file2:
            print line

如果数据比这个大,你可能需要查看实际的数据库和一些简单的 SQL。它们适用于大数据。

答案3

并且 python 选项:无论所有单词是否在一行中还是在不同的行中:

#!/usr/bin/env python3

import sys

f1 = sys.argv[1]; f2 = sys.argv[2]

def read(f):
    with open(f) as content:
        return content.read().split()

for item in [w for w in read(f1) if not w in read(f2)]:
    print(item)

将脚本复制到一个空文件中,保存为showdiff.py可执行文件并通过以下命令运行它:

/path/to/showdiff.py file1 file2

anna
laura

笔记

这不是问题,但有太多相关内容不容忽略:

如果你需要列出差异相互,(不仅包括 中file1没有出现的单词file2,还包括file2中没有出现的单词file1),应使用以下脚本:

#!/usr/bin/env python3

import sys

f1 = sys.argv[1]; f2 = sys.argv[2]

def read(f):
    with open(f) as content:
        return content.read().split()

wds1 = read(f1); wds2 = read(f2); allwords = wds1+wds2
for item in [w for w in allwords if (w in wds1, w in wds2).count(False) == 1]:
    print(item)

答案4

如果你按照 Jacob Vlijm 的建议使用 python 选项,那么值得使用 'set'(有关更多信息,请参阅https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset)。基本上,一旦您创建了这两个集合,您就可以实现集合数学(并集、交集、差集……)。
在这种情况下,集合差集正是您所需要的:一个新集合,其中包含一个集合中的所有元素,而不包含在另一个集合中。Jacob
的代码将是:

#!/usr/bin/env python3

import sys

f1 = sys.argv[1]; f2 = sys.argv[2]

def read_set(f):
    with open(f) as content:
        return set(content.read().split())

for item in read_set(f1) - read_set(f2)]:
    print(item)

当然,对于数十亿条记录来说,这需要一段时间......'

相关内容