awk для сравнения двух файлов, извлечения, вывода в третий [закрыто]

Я написал сценарий на Python, но он недостаточно быстр для этой работы. Я думаю построчно. обработка будет работать лучше.

У меня есть два файла с двумя столбцами и потенциально сотнями миллионов строк (биоинформатика). Два файла (file1, file2) похожи, разделены табуляцией, причем первый столбец содержит строки букв и цифр, а второй столбец содержит целые числа. Заголовки - это имя , количество в каждом файле.

Мне нужно создать файл с разделителями табуляции, в котором: первая запись каждой строки берется из столбца имя , но только те имена, которые есть в обоих file1 и ] file2 , вторая запись - это счетчик для этого имени из файла 1; и третья запись - это счетчик для этого имени из file2 с сохранением заголовков.

После долгого чтения вот моя попытка:

awk '(NR == FNR) {
   n0[$1] = 0; 
   n1[$1] = 0; 
   next
 }     {
   if($1 in n0) {
     n2[$2] = 0
   }
 } END {
   for (i in n0) (j in n1) (k in n2) {
     print i,"\t",j,"\t",k
   } 
}' file1 file2

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

Если бы кто-то мог исправить сценарий awk, используя тот же базовый синтаксис потока, что и в приведенном выше, это было бы превосходно и очень ценно.

также, что нужно сделать, чтобы преобразовать его в исполняемый файл .sh?

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

1
задан 28 March 2015 в 20:06

2 ответа

Вы были бы очень более обеспечены, если Ваш вход отсортирован на первом столбце, с тех пор можно непосредственно использовать join команда:

$ cat foo 
a   1
b   2
c   3
d   4
$ cat bar
b   1
d   4
e   5
n   2
$ join -t  

В любом случае, я рекомендовал бы сортировать - без сортировки, Вы потенциально смотрите O(m*n) операции, но с сортировкой, O(m*log(m) + n*log(n) + min(m,n)) операции - она должна сохранить Вас некоторое время при оптимизации методов вместо языка, Вы используете.

С awk, можно сойти с рук единый массив:

awk 'NR==FNR { n[$1] = $2; next } ($1 in n) {print $1, n[$1], $2}' foo bar

Это должно быть довольно быстро также, если $i in n.

\t' <(sort foo) <(sort bar) b 2 1 d 4 4

В любом случае, я рекомендовал бы сортировать - без сортировки, Вы потенциально смотрите O(m*n) операции, но с сортировкой, O(m*log(m) + n*log(n) + min(m,n)) операции - она должна сохранить Вас некоторое время при оптимизации методов вместо языка, Вы используете.

С awk, можно сойти с рук единый массив:

awk 'NR==FNR { n[$1] = $2; next } ($1 in n) {print $1, n[$1], $2}' foo bar

Это должно быть довольно быстро также, если $i in n.

3
ответ дан 28 March 2015 в 20:06

С bash:

Принятие file1:

abc123 123456
def456 789123
ghi789 456789

И file2:

abc123 789123

Это произведет file3:

abc123 123456 789123
#!/bin/bash

while read line1; do
    var1=$(echo $line1 | tr '\t' '\n')
    while read line2; do
        var2=$(echo $line2 | tr '\t' '\n')
        if [ "${var1[0]}" == "${var2[0]}" ]; then
            printf "%s\t%s\t%s\n" "${var1[0]}" "${var1[1]}" "${var1[2]}"
        fi
    done < file2
done < file1
2
ответ дан 28 March 2015 в 20:06

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

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