我有一个制表符分隔的文件,如下所示:
$ 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_1
,input_file_2
...
答案2
您可以测试以下代码,其中我将关键字拆分到一个以元素awk
命名的数组 中。一切都以keys[1]开始,我们设置一个标志来检查接下来的1行是否与数组keys[索引从2到N]中的相应值匹配,N-1行之前的任何不匹配都会重置该标志,如果到达该行,则所有内容都适合输出(我们还在这里重置 flag=0,因此连续运行 flag==1 永远不会超过行数):keys
N
N-1
N-1
N-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="..."
以使其更加灵活。