Используя только совпадающие записи, выведите строку файла A, если значения столбцов находятся между двумя значениями других столбцов в файле B - PullRequest
0 голосов
/ 21 июня 2019

У меня есть разделитель табуляции file1

A 1
A 20
B 17
B 33
C 10
C 20
E 7

и другой разделитель табуляции file2

A 1  5
A 6  20
B 1  10
B 30 60
C 10 20
E 1  6

Мне нужно напечатать строки в file1, для которых col1 file1 = col1 file2 и значение вcol2 file1 попадает в диапазоны в cols 2 и 3 файла 2.

Вывод будет выглядеть как

A 1
A 20
B 33
C 10
C 20

Я пытаюсь

awk 'FNR==NR{a[$1]=$2;next}; ($1) in a{if($2=(a[$1] >= $2 && a[$1] <=$3) {print}}1'  file1  file2 

Но это не такработа.

Ответы [ 2 ]

1 голос
/ 22 июня 2019

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

awk '
    # store each range from file2
    FNR==NR {
        n = ++q[$1]
        min[$1 FS n] = $2
        max[$1 FS n] = $3
        next
    }

    # process file1
    n = q[$1] { # if no q entry, line cannot be in range
        for (i=1; i<=n; i++)
            if ( min[$1 FS i]<=$2 && $2<=max[$1 FS i]) {
                print
                next
            }
    }
' file2 file1

Каждый мин / макс диапазон должен храниться отдельно. Поддерживая счетчик (q[$1]) вхождений каждого отдельного значения col1 ($1), мы обеспечиваем создание отдельного нового элемента массива [$1 FS n].

Впоследствии, при проверке диапазонов, мы знаем, что любое конкретное значение col1 встречается точно q[$1] раз.

0 голосов
/ 23 июня 2019

Мое отчаянное решение этого было манипулировать моим файлом2 в этом, используя некоторые базовые операции awk

A 1 gene_starts
A 5 gene_ends
A 6 gene_starts
A 20 gene_ends
B 1 gene_starts
B 10 gene_ends
B 30 gene_starts
B 60 gene_ends
C 10 gene_starts
C 20 gene_ends
E 1 gene_starts
E 6 gene_ends

Так, чтобы я мог отсортировать два файла 1 и 2 и захватить строки между gene_starts и genes_ends

sort -V -k1,2 file1 file2 | awk '/gene_starts/,/gene_ends/' | awk '!length($3)' 

Но это позволило мне получить только

A 20
B 33
C 20

, потому что сортировка помещает строки из file1, соответствующие gene_starts, перед ними.Итак, чтобы получить A 1 и C 10, мне пришлось сделать фильтр gene_ends из моего file2 и использовать

awk 'NR==FNR{c[$1,$2];next} (($1,$2) in c)' file2 file1

, чтобы получить строки gene_starts, которые также были в file1, и добавить их к моему выводу

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