按顺序挑选包含关键词的连续行

按顺序挑选包含关键词的连续行

我有一个制表符分隔的文件,如下所示:

$ cat file
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011558474.1  1159543 1160595 -4330977        polyketide synthase [Mycobacterium]
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011558475.1  1160607 1161116 12      isoprenylcysteine carboxyl methyltransferase [Mycobacterium]
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011558476.1  1161113 1162129 -3      NAD(P)/FAD-dependent oxidoreductase [Mycobacterium]
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011559726.1  2496640 2497560 1334511 polyketide synthase [Mycobacterium]
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011559727.1  2497568 2498122 8       isoprenylcysteine carboxyl methyltransferase [Mycobacterium]
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011562574.1  5526997 5528142 3028875 NAD(P)/FAD-dependent oxidoreductase [Mycobacterium]

我需要去接连续的行包含关键字“聚酮合酶”、“甲基转移酶”和“氧化还原酶”以该顺序,并将每个集合写入单独的文件中以供进一步分析。

在这种情况下,输入文件将产生 2 个输出文件,如下所示:

$ cat file_1
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011558474.1  1159543 1160595 -4330977        polyketide synthase [Mycobacterium]
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011558475.1  1160607 1161116 12      isoprenylcysteine carboxyl methyltransferase [Mycobacterium]
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011558476.1  1161113 1162129 -3      NAD(P)/FAD-dependent oxidoreductase [Mycobacterium]

$ cat file_2
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011559726.1  2496640 2497560 1334511 polyketide synthase [Mycobacterium]
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011559727.1  2497568 2498122 8       isoprenylcysteine carboxyl methyltransferase [Mycobacterium]
GCF_000015405.1_ASM1540v1.dist_nbr_anntn        WP_011562574.1  5526997 5528142 3028875 NAD(P)/FAD-dependent oxidoreductase [Mycobacterium]

我很难使用 awk 来做到这一点。有什么建议么?

聚苯乙烯我有其他输入文件,其中连续行中包含可变数量的关键字实例。这就是我陷入困境的地方。

答案1

您可以随着脚本的进展更改要搜索的内容,并更改每次循环浏览术语时的写入位置

awk 'BEGIN {
    result_file = 1;
    term_id = 1;
    search_terms[1] = "polyketide synthase";
    search_terms[2] = "methyltransferase";
    search_terms[3] = "oxidoreductase"
}
$0 ~ search_terms[term_id] { 
    print $0 >> FILENAME "_" result_file;
    term_id = term_id + 1;
    if (term_id > 3) {
        result_file =  result_file + 1;
        term_id = 1
    }
}' input_file

这将写信给input_file_1input_file_2...

答案2

您可以测试以下代码,其中我将关键字拆分到一个以元素awk命名的数组 中。一切都以keys[1]开始,我们设置一个标志来检查接下来的1行是否与数组keys[索引从2到N]中的相应值匹配,N-1行之前的任何不匹配都会重置该标志,如果到达该行,则所有内容都适合输出(我们还在这里重置 flag=0,因此连续运行 flag==1 永远不会超过行数):keysNN-1N-1N-1

$ cat t24.awk
BEGIN{ 
    FS = OFS = "\t";
    keywords = "polyketide synthase,methyltransferase,oxidoreductase";
    N = split(keywords, keys, ",")
}

# flag==1 means we are doing regex_match the next N-1 lines
# against corresponding array element in keys from [2:N] 
# once a unmatched found, turn off flag immediately
# if the flag==1 reached N-1 lines, then print the good match
flag {
    if($NF ~ keys[NR - start_line + 1]) {
        F = F ORS $0;
        if (NR == start_line+N-1) {print F > "out_" f++; flag = 0 }
        next
    } else {
        flag = 0;
    }
}

# set up the flag/start_line and reset F
$NF ~ keys[1] { flag = 1; F = $0; start_line= NR; }

使用 运行上面的代码awk -f t24.awk file.txt。您可以keywords从 shell 中设置(以逗号分隔)(而不是在BEGIN块中硬编码),然后使用-v keywords="..."以使其更加灵活。

相关内容