You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取匹配指定ID的Hit行及对应Query行?

解决方案:用Awk一次性关联Query与匹配的Hit记录

首先,你的核心需求是:保留File.txt中的Query记录,同时只保留那些Hit记录里包含ID.txt中指定ID的条目,并且保证Query和对应的Hit正确关联。你之前用循环调用Awk的方式存在几个关键问题:

  • 每次循环都会覆盖output.txt,最后只会留下最后一个ID的匹配结果
  • Awk单引号内的"$i"无法正确传递shell变量,因为单引号会屏蔽shell变量解析
  • 没有维护Query和Hit的关联关系,容易出现重复输出Query或丢失对应关系的情况

完全不需要shell循环,用Awk就能一次性完成所有操作,效率更高也更准确。

正确的Awk命令

awk '
BEGIN {
    # 先读取ID.txt里的所有ID,存入数组id_map,实现快速查找
    while (getline < "ID.txt") {
        id_map[$0] = 1
    }
    close("ID.txt")
    current_query = ""
    query_printed = 0
}
# 遇到Query行时,记录当前Query,并标记该Query未输出
/^Query:/ {
    current_query = $0
    query_printed = 0
    next
}
# 处理Hit行:检查Hit后的第一个字段是否在指定ID集合中
/^Hit:/ {
    hit_id = $2
    if (id_map[hit_id]) {
        # 如果当前Query还未输出,先打印Query
        if (!query_printed) {
            print current_query
            query_printed = 1
        }
        # 打印匹配的Hit行
        print $0
    }
}
' File.txt > output.txt

命令细节解释

  1. BEGIN块:在处理目标文件File.txt之前,先读取ID.txt的所有内容,将每个ID作为数组id_map的键存储,这样后续判断ID是否存在的操作是O(1)级别的,非常高效。
  2. Query行处理:每当匹配到Query:开头的行,就将该行内容存入current_query变量,同时把query_printed标记为0(表示这个Query还未被输出过)。
  3. Hit行处理:匹配到Hit:开头的行时,提取Hit后的第一个字段(即$2,比如AMP2_FAGES),检查它是否在id_map中。如果存在:
    • 若当前Query还未输出,先打印该Query
    • 接着打印当前的Hit行
  4. 最终结果重定向到output.txt,不会像循环方式那样反复覆盖文件内容。

验证结果

用你提供的测试数据运行该命令后,output.txt的内容会和你期望的完全一致:

Query: PROKKA_00022 hypothetical protein - 36 aa
Hit: AMP2_FAGES UniProt Fag e 4 UniProt P0DKH8 http://www.u 100.0% identity
Hit: Q6JYQ7_HEVBR UniProt Hev b 6 UniProt Q6JYQ7 http://www 100.0% identity
Query: PROKKA_00572 hypothetical protein - 36 aa
Hit: AMP2_FAGES UniProt Fag e 4 UniProt P0DKH8 http://www.u 100.0% identity
Hit: Q6JYQ7_HEVBR UniProt Hev b 6 UniProt Q6JYQ7 http://www 100.0% identity

内容的提问来源于stack exchange,提问作者Susheel Busi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 13:02:40