2014-01-13 3 views
0

У меня есть два файла с разделителями табуляции. Мне нужно сравнить файл 1 столбец 3 с файлом 2 столбец 1. Если есть совпадение, мне нужно написать столбец 2 файла 2 рядом с соответствующей строкой в файле 1.here образец моего файла:python или awk, сравнивающие файлы

файла 1:

a rao rocky1 beta 

b rao buzzy2 beta 

c Rachel rocky2 alpha 

файл 2:

rocky1 highlightpath 

rimper2 darkenpath 

rocky2 greenpath 

выход:

новый файл:

a rao rocky1 beta highlightpath 

b rao buzzy2 beta 

c Rachel rocky2 alpha greenpath 

проблема в файле 1 огромна! файл 2 также большой, но не так много. До сих пор я пробовал команду awk, она работала частично. я имею в виду количество строк в файле 1 и выходной файл, который является новым файлом, должен быть таким же, а это не то, что я получил! Я получаю разницу в 20 строк.

awk 'FNR==NR{a[$3]=$0;next}{if($1 in a){p=$1;$1="";print a[p],$0}}' file1 file2 > newfile 

Так я думал, что я мог бы попробовать питон, чтобы сделать это, но я новичок в Python. Все, что я знаю до сих пор, я хотел бы сделать словарь для файла 1 и файла 2 и сравнить. Я знаю, как читать файл в словаре, а затем я пустой. Любая помощь и предложение с кодом помогут. Благодаря

ответ

1
import sys 

# Usage: python SCRIPT.py FILE1 FILE2 > OUTPUT 
file1, file2 = sys.argv[1:3] 

# Store info from the smaller file in a dict. 
d = {}  
with open(file2) as fh: 
    for line in fh: 
     k, v = line.split() 
     d[k] = v 

# Process the bigger file line-by-line, printing to standard output. 
with open(file1) as fh: 
    for line in fh: 
     line = line.rstrip() 
     k = line.split()[2] 
     if k in d: 
      print line, d[k] 
     else: 
      print line 
+0

@ user2464553 Я видел ваш комментарий. Если вы получаете индексную ошибку, это означает, что некоторые из строк в FILE1 имеют меньше полей, чем вы думаете: 'split()' возвращает список, а '[2]' пытается получить 3-й элемент списка. Просто добавьте некоторую условную логику для обработки этой ситуации. – FMc

+0

Хорошо спасибо FMc! Попробуем это :) Спасибо за вашу помощь :) – user2464553

0
with open('outfile.txt', 'w') as outfile: 
    with open('file1.txt', 'r') as f1: 
      with open('file2.txt', 'r') as f2: 

       for f1line in f1: 
        for f2line in f2: 
         ## remove new line character at end of each line 
         f1line = f1line.rstrip() 
         f2line = f2line.rstrip() 

         ## extract column fields 
         f1col3 = f1line.split('\t')[2] 
         f2col1 = f2line.split('\t')[0] 

         ## test if fields are equal 
         if (f1col3 == f2col1): 
           outfile.write('%s\t%s\n' % (f1line, 
                  f2line.split('\t')[1])) 
         else: 
           outfile.write('%s\t\n' % (f1line)) 

         break 
  • Этот сценарий будет сравнить lines1 из file1 & 2, то lines2 из file1 & 2 lines3 ... и т.д. ...
  • Это хорошо для больших файлов; не следует загружать память :)
+0

В F2 for-loop существует 'break', поэтому итератор файла F2 не будет исчерпан после обработки одной строки из F1 ... правильно? – csiu

+0

Да, не поймал 'break' - я думаю, потому что это такой неожиданный способ обработки двух файлов параллельно. Возможно, вы могли бы полностью отказаться от внутреннего цикла и просто использовать 'f2line = next (f2, '')', который, кажется, передает алгоритм более прямо - просто предложение. Удалит мой первый комментарий. – FMc

0

file2 настроенные быть ассоциативным массивом, и это меньшее из двух файлов, так что я снова расположил AWK немного, чтобы получить:

awk 'NR==FNR { if(length($1) > 0) a[$1]=$2; next} { if($3 in a) {print $0,a[$3] } else { print $0 } }' file2 file1 > newfile 
  1. По какой-то причине моя машина не создавала a[], пока я не повторно заказал тест NR == FNR, так что это небольшая разница. Также обратите внимание, что я сделал первый файл, переданный awk file2. Непустые строки от file2 добавлены к a[].
  2. Обработайте каждую строку от file1 во-вторых и добавьте данные столбца file2 в строку, если $3 в файле1 находится в a[]. Просто просто напечатайте строку как есть.

Запуск выше, я получаю желаемый результат на двух разных машинах с разными версиями AWK (от генерируемого newfile):

a rao rocky1 beta highlightpath 

b rao buzzy2 beta 

c Rachel rocky2 alpha greenpath 
0

Вот более короткий awk

awk 'NR==FNR {a[$1]=$2;next} {print $0,$3 in a?a[$3]:""}' file2 file1 
a rao rocky1 beta highlightpath 

b rao buzzy2 beta 

c Rachel rocky2 alpha greenpath 
0

Рассмотрение всех предложений вместе: Я не получаю ни одного из них для работы! Может, из-за пустых строк в моем файле 2? Ну, линии не полностью пусты.например:

rocky1 highlightpath

rimper2 darkenpath

rocky2 greenpath

lacy2

lucy1 pembrooke

теперь, когда я побежал коды питона, приведенные выше, я использовал исправленный файл 2, где я снял строки пробелов (например, lacy2), а затем использовал файл. Eventhen я получаю индекс списка вне диапазона. Не соответствует ли список, создаваемый с помощью строк из файла? Похоже на то. Прошу прокомментировать :)

Смежные вопросы