blastn输出文件序列ID不匹配行提取及通用列匹配行导出技术问询
嘿,针对你这两个文本处理需求,我给你整理了高效的解决方案——毕竟几万行的blastn文件,用shell工具处理比写脚本快太多了:
1. 提取BLASTn输出中query与subject部分ID不匹配的行
首先看你的blastn输出是空格分隔的tabular格式,第一列是qseqid,第五列是sseqid(对应你给的字段顺序:qseqid qlen qstart qend sseqid ...)。
核心是先定义清楚“部分内容”的规则,比如你示例里的qseqid是OFAS003927-RA-EXON03_Acanthocephalini_Acanthocephala_alata_CMF_0025_S10_L...,假设你要对比的是下划线分隔的第3个字段(也就是Acanthocephalini)和sseqid里的对应字段,那用awk就能轻松实现:
awk '{ # 拆分qseqid为下划线分隔的数组 split($1, q_parts, "_"); # 拆分sseqid为下划线分隔的数组 split($5, s_parts, "_"); # 对比第3个字段(根据你的实际需求调整索引,比如改成4就是下一个字段) if (q_parts[3] != s_parts[3]) { print $0 > "blastn_mismatched.txt" } }' your_blastn_output.txt
如果你的“部分内容”是其他规则(比如物种名片段、前缀后缀),只需要修改split后的对比逻辑就行。比如要对比qseqid里的Acanthocephala_alata和sseqid的对应部分:
awk '{ split($1, q_parts, "_"); split($5, s_parts, "_"); # 拼接第4+5个字段作为物种名 q_species = q_parts[4] "_" q_parts[5]; s_species = s_parts[4] "_" s_parts[5]; if (q_species != s_species) print $0 > "blastn_mismatched.txt" }' your_blastn_output.txt
2. 通用需求:提取两列部分内容匹配的行到新文件
这个场景更灵活,核心是指定要对比的列+定义匹配规则,同样用awk就能搞定各种情况:
场景1:两列前缀匹配(比如前10个字符相同)
假设对比第1列和第5列的前10个字符,匹配就输出:
awk '{ if (substr($1, 1, 10) == substr($5, 1, 10)) { print $0 > "matched_lines.txt" } }' your_file.txt
场景2:某列包含另一列的特定子串
比如第5列包含qseqid里的EXON开头的片段:
awk '{ # 从qseqid里提取EXON开头的部分 exon_part = substr($1, index($1, "EXON"), 5); # 如果sseqid里包含这个片段,就输出 if (index($5, exon_part) != 0) { print $0 > "matched_lines.txt" } }' your_file.txt
场景3:正则匹配相同模式的内容
比如对比两列里的OFAS开头的数字前缀:
awk '{ # 用正则提取OFAS+数字的部分 match($1, /OFAS[0-9]+/, q_match); match($5, /OFAS[0-9]+/, s_match); if (q_match[0] == s_match[0]) { print $0 > "matched_lines.txt" } }' your_file.txt
实用提示:
- 几万行的文件用awk完全hold住,处理速度比Python这类脚本快不少;
- 如果你的文件是制表符分隔,记得给awk加
-F'\t'参数; - 所有规则都可以根据你的实际需求调整,awk的字符串处理函数(
split/substr/index/match)能覆盖绝大多数场景。
内容的提问来源于stack exchange,提问作者Mike F
相关产品推荐
相关产品推荐

