Извлечение определенных строк в список ребер - PullRequest
0 голосов
/ 29 октября 2018

У меня большой сетевой файл с миллионами ненаправленных ребер : edge.txt с узлом 1 , узлом 2 и некоторыми числовыми атрибутами

a   b   0.8
b   c   0.1
d   f   0.7
e   f   0.5
c   b   0.1
b   a   0.8
a   c   0.1

Дан другой файл input.txt

a
b
c

Должны быть напечатаны только те ребра, которые имеют оба узла (node1 и node2) в input.txt

a   b   0.8
b   c   0.1
a   c   0.1

Я пытался:

awk 'FNR==NR {a[$0]++;next}{if ($1 in a && $2 in a) {print}}' input.txt edge.txt

Нужны предложения? Спасибо

Ответы [ 3 ]

0 голосов
/ 29 октября 2018

Еще один, который пытается свести к минимуму поиск хеша b, если edge >> input:

$ awk '
NR==FNR && !($1 in a) {   # if node not in hash a yet, ie. remove duplicates in input
    for(i in a) {         # "c" -> a[]: insert to b: ca, ac, cb, bc
        b[$1 i]
        b[i $1]
    }
    a[$1]                 # new entries go to a as well
    next
}
($1 $2 in b) {
    # delete b[$1 $2]     # uncomment these to remove duplicates
    # delete b[$2 $1]     # ie. "a b 0.8" vs. "b a 0.8"
    print
}' input edge  # if both $1 and $2 are in a, $1 $2 is in b

Выход:

a   b   0.8
b   c   0.1
c   b   0.1
b   a   0.8
a   c   0.1

С удаленными дубликатами:

a   b   0.8
b   c   0.1
a   c   0.1
0 голосов
/ 29 октября 2018

@ Олив метод правильный, но если вы хотите удалить транспонированные пары, вам нужно добавить еще несколько условий

$ awk 'NR==FNR{a[$1]=1; next} a[$1] && a[$2] && !b[$1,$2]++ && !b[$2,$1]++' input edge

a   b   0.8
b   c   0.1
a   c   0.1
0 голосов
/ 29 октября 2018

Вы можете попробовать этот awk скрипт:

awk 'NR==FNR{a[$1];next}($1 in a)&&($2 in a)' input.txt edge.txt

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...