Как я могу сравнить 3 файла вместе (чтобы увидеть, что общего между ними)? - PullRequest
0 голосов
/ 01 ноября 2011

Я хочу сравнить 3 файла вместе, чтобы увидеть, сколько информации в файлах одинаково. Формат файла примерно такой:

Chr11   447     .       A       C       74      .       DP=22;AF1=1;CI95=1,1;DP4=0,0,9,8;MQ=15;FQ=-78   GT:PL:GQ        1/1:107,51,0:99
Chr10   449     .       G       C       35      .       DP=26;AF1=0.5;CI95=0.5,0.5;DP4=5,0,7,8;MQ=20;FQ=11.3;PV4=0.055,0.0083,0.028,1   GT:PL:GQ        0/1:65,0,38:41
Chr12   517     .       G       A       222     .       DP=122;AF1=1;CI95=1,1;DP4=0,0,77,40;MQ=23;FQ=-282       GT:PL:GQ        1/1:255,255,0:99
Chr10   761     .       G       A       41      .       DP=93;AF1=0.5;CI95=0.5,0.5;DP4=11,34,6,35;MQ=19;FQ=44;PV4=0.29,1.8e-35,1,1      GT:PL:GQ        0/1:71,0,116:74

Меня интересуют только первые два столбца (если первые два столбца совпадают, я считаю его равным). Это команда, которую я использую для сравнения двух файлов:

awk 'FILENAME==ARGV[1] {pair[$1 " " $2]; next} ($1 " " $2 in pair)'  file1 file2 | wc -l

Я бы хотел использовать команду awk, так как мои файлы действительно большие и awk обрабатывает их очень хорошо! но я не мог понять, как использовать его для 3 файлов!

Ответы [ 4 ]

2 голосов
/ 06 февраля 2014

Не предназначен для начала войны редакторов, но я знаком с VI, и vimdiff и его варианты показывают сравнение между несколькими файлами в параллельном представлении, что я считаю очень удобным. Просто вы можете позвонить с помощью

$ vimdiff <filelist>
2 голосов
/ 01 ноября 2011

Просто прочитайте свой последний комментарий - Вы хотите, чтобы файлы объединились, но дубликаты были удалены?

 sort file1 file2 file3 | uniq > newfile
2 голосов
/ 01 ноября 2011

Если просто распечатать пары (column1 + column2), которые являются общими для всех трех файлов, и использовать тот факт, что пара является уникальной в файле, вы можете сделать это следующим образом:

awk '{print $1" "$2}' a b c | sort | uniq -c | awk '{if ($1==3){print $2" "$3}}'

Это можно сделать с произвольным количеством файлов, если вы измените параметр последней команды.

Вот что он делает:

  1. печатает и сортирует первые 2 столбца всех файлов (awk '{print $1" "$2}' a b c | sort)
  2. подсчитать количество повторяющихся записей (uniq -c)
  3. если количество повторяющихся записей == количество файлов, мы нашли совпадение. распечатай.

Если вы делаете это часто, вы можете выразить это как функцию bash (и добавить ее в .bashrc), которая параметризует количество файлов.

function common_pairs { 
    awk '{print $1" "$2}' $@ | sort | uniq -c | awk -v numf=$# '{if ($1==numf){print $2" "$3}}'; 
}

Позвоните по любому желаемому количеству файлов: common_pairs file1 file2 file3 fileN

2 голосов
/ 01 ноября 2011

Для этого я бы использовал команды cut , sort и comm .

  1. С cut вырезать ненужные поля.

  2. sort результат с comm ожидает отсортированный ввод.

  3. Используйте comm , чтобы получить строки, находящиеся в файле1 и файле2.

  4. Используйте comm снова, чтобы получить строки, которые также есть в файле 3.

Сценарий может выглядеть следующим образом:

 for i in 1 2 3
  do
   # options to cut may have to be adjusted for your input files
   cut -c1-15 file$i | sort > tmp.$i
  done

 comm -12 tmp.1 tmp.2   > tmp.1+2
 comm -12 tmp.3 tmp.1+2 > tmp.1+2+3

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

В файле tmp.1+2+3 теперь вы должны иметьключи присутствуют во всех трех файлах.Если вас интересуют целые строки, вы можете использовать команду join в сочетании с отсортированной версией любого из трех файлов ввода)

...