Я написал сценарий на 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?
из элементов первого столбца двух файлов (только те элементы, которые присутствуют в обоих из двух файлов, находят пересечение значений между двумя файлами в первом столбце, а затем
Вы были бы очень более обеспечены, если Ваш вход отсортирован на первом столбце, с тех пор можно непосредственно использовать 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
.
С 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