grep и напечатать, сколько раз мой шаблон в файле 1 присутствует в файле2

У меня есть файл1 (список моего шаблона), например:

file1

Fatty_acid_degradation Aminobenzoate_degradation Amino_sugar_and_nucleotide_sugar_metabolism Amoebiasis 

и у меня есть файл2 (список всех шаблонов).

file2

 Fatty_acid_degradation Fatty_acid_degradation Fatty_acid_degradation Bacterial_invasion_of_epithelial_cells Bacterial_invasion_of_epithelial_cells Bacterial_invasion_of_epithelial_cells Bacterial_invasion_of_epithelial_cells 

Я хотел бы grep и подсчитать, сколько раз каждый из моих шаблонов в файле1 присутствует в файле2 и получает таблицу (разделяемую вкладку) следующим образом:

 Fatty_acid_degradation 3 

Самый простой подход состоял бы в том, чтобы grep каждого из шаблонов, а затем посчитать их:

 $ grep -Fwf file1 file2 | sort | uniq -c 3 Fatty_acid_degradation 

Параметры grep : -f чтобы предоставить файл в виде списка шаблонов для поиска, -F чтобы указать, что шаблон следует рассматривать как строку, а не регулярное выражение, и -w чтобы гарантировать, что шаблон сопоставляется только с целым слова (так что выражение regulation_of_expression не сопоставляется с upregulation_of_excpression например).

Затем вы можете использовать любой инструмент, который вы предпочитаете изменить формат:

 $ grep -Fwf file1 file2 | sort | uniq -c | sed -r 's/.*([0-9]+) *(.*)/\2\t\1/' $ grep -Fwf file1 file2 | sort | uniq -c | perl -lane 'print "$F[1]\t$F[0]"' $ grep -Fwf file1 file2 | sort | uniq -c | awk -vOFS="\t" '{print $2,$1}' 

Все приведенное выше возвращение

 Fatty_acid_degradation 3 
 grep -f file1 file2 | sort | uniq -c 

Это дает результат в формате:

  3 Fatty_acid_degradation 

Можете ли вы с этим жить?

так много быстрого ответа, заставляют меня чувствовать себя неловко …

 awk 'FNR == NR { pat[$1]=0 ; next ; } { if ( $0 in pat ) pat[$0]++ ; } END { for ( p in pat ) if ( pat[p]) printf "%s %d\n",p,pat[p] ;}' f1 f2 

где

  • FNR == NR { pat[$1]=0 ; next ; } FNR == NR { pat[$1]=0 ; next ; } шаблон записи в массиве pat
  • { if ( $0 in pat ) pat[$0]++ ; } { if ( $0 in pat ) pat[$0]++ ; } всякий раз, когда вы соответствуете, подсчитывайте
  • END { for ( p in pat ) if ( pat[p]) printf "%s %d\n",p,pat[p] ;} в конце, сбрасывает ненулевой счет

Вы также можете попробовать следующее решение с помощью Python:

 #!/usr/bin/env python2 import collections with open('file_1') as f1, open('file_2') as f2: counts = collections.Counter(f2) for line in f1: if line in counts: print line.rstrip() + '\t' + str(counts[line]) 

Здесь мы использовали модуль collections Counter который будет генерировать словарь, содержащий вхождения каждого элемента итерабельного.