Как я мог содержать имена в первом файле, которые не являются мной?

У меня есть два файла, содержащие миллиарды имен последовательности DNA, вторым является собственное подмножество первого:

например,

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

2°:john mike paul ...

все имена занимают одну строку.

Мой вопрос, как я мог содержать имена в первом файле, которые не находятся во втором?

благодарите u все!

3
задан 19 September 2014 в 17:37

4 ответа

Это очень просто сделать, но Ваша жизнь будет намного легче, если у Вас будет одно имя на строку вместо разделенного списка пространства. Существует много превосходных утилит для управления текстовыми файлами в Linux, это - одна из вещей, в которых все *отклоняют Excel, но большинство ожидает один объект на строку. Так, большинство моих решений запустится с изменения файлов соответственно.

Измените свои файлы, чтобы иметь одно имя на строку:

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
ответ дан 1 December 2019 в 15:25

Если они отсортированы и разделены новыми строками, Вы могли бы использовать 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. Они приспособлены для больших данных.

2
ответ дан 17 November 2019 в 19:43

И опция 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)
2
ответ дан 17 November 2019 в 19:43

Если Вы идете опция Python, как предложил Jacob Vlijm, стоит использовать 'набор' (для дальнейшей информации, см. 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)

Конечно, для миллиардов записей, это будет требовать времени...'

0
ответ дан 17 November 2019 в 19:43

Другие вопросы по тегам:

Похожие вопросы: