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

当字段$2为rev时对$4、$5字段执行reverse与tr转换的技术需求

问题描述

输入文本

m64071_220512_054244/12584899/ccs rev pet047-10055 ACGTGCGACCTTGTGA TTGAGGGTTCAAACGTGCGACCTTGTGA
m64071_220512_054244/128321000/ccs rev pet047-10055 ACGTGCGACCTTGTGA TTGAGGGTTCAAACGTGCGACCTTGTGA
m64071_220512_054244/132186699/ccs fwd pet047-10055 TCACAAGGTCGCACGT TCACAAGGTCGCACGTTTGAACCCTCAA
m64071_220512_054244/134874748/ccs fwd pet047-10055 TCACAAGGTCGCACGT TCACAAGGTCGCACGTTTGAACCCTCAA

需求

仅当第2个字段值为rev时,对第4、5字段执行反转字符串+碱基互补转换(ATGC ↔ TACG);fwd行保持原样。

预期输出

m64071_220512_054244/12584899/ccs rev pet047-10055 TCACAAGGTCGCACGT TCACAAGGTCGCACGTTTGAACCCTCAA
m64071_220512_054244/128321000/ccs rev pet047-10055 TCACAAGGTCGCACGT TCACAAGGTCGCACGTTTGAACCCTCAA
m64071_220512_054244/132186699/ccs fwd pet047-10055 TCACAAGGTCGCACGT TCACAAGGTCGCACGTTTGAACCCTCAA
m64071_220512_054244/134874748/ccs fwd pet047-10055 TCACAAGGTCGCACGT TCACAAGGTCGCACGTTTGAACCCTCAA

原尝试的问题

Perl命令问题

原命令逻辑和语法都有问题:

perl -lpe 'if(/rev/) {$rev=/rev/;next}; if ($rev) {$F[4,5]=~tr/ATGC/TACG/; $F[4,5]=reverse $F[4,5]; print "@F"}' file 
  • 未加-a参数,无法自动拆分字段到@F数组,数组为空
  • 匹配到rev后直接next跳过处理,后续逻辑根本不会执行
  • 碱基转换和反转的顺序逻辑混乱,且未针对目标字段正确操作

Awk命令问题

原命令存在变量错误和效率问题:

awk '{
            if($2==rev)
        {
            cmd1="echo \047" $4 "\047 | rev | tr \047ATGC\047 \047TACG\047" 
            cmd2="echo \047" $5 "\047 | rev | tr \047ATGC\047 \047TACG\047"
            newVar1=((cmd1 | getline line) > 0 ? line : "failed") 
            newVar2=((cmd2 | getline line) > 0 ? line : "failed")
            close(cmd)
            print $1, $2, $3, newVar1, newVar2
        }
        else {print}
}' file
  • $2==rev中rev是未定义变量,应该写$2=="rev"
  • close(cmd)中的cmd未定义,需分别关闭cmd1和cmd2
  • 调用外部rev/tr命令效率低,Awk本身可实现对应功能

正确解决方案

方案1:Perl命令

利用Perl内置的字段拆分和字符串处理能力,无需外部命令:

perl -alne '
    if ($F[1] eq "rev") {
        # 处理第4、5字段(数组索引3、4)
        for my $i (3,4) {
            $F[$i] = reverse $F[$i];
            $F[$i] =~ tr/ATGC/TACG/;
        }
    }
    print join(" ", @F);
' file
  • -a参数自动按空格拆分字段到@F数组(索引从0开始)
  • 直接在Perl内完成反转+互补,效率更高
  • 逻辑清晰,严格匹配rev字段后处理目标内容

方案2:Awk命令

用Awk自定义函数实现反转和互补,避免外部命令开销:

# 定义碱基互补转换函数
function complement(s) {
    gsub(/A/, "X", s); gsub(/T/, "A", s); gsub(/X/, "T", s);
    gsub(/G/, "Y", s); gsub(/C/, "G", s); gsub(/Y/, "C", s);
    return s;
}
# 定义字符串反转函数
function reverse(s) {
    res = "";
    for (i = length(s); i > 0; i--) {
        res = res substr(s, i, 1);
    }
    return res;
}
{
    if ($2 == "rev") {
        $4 = complement(reverse($4));
        $5 = complement(reverse($5));
    }
    print $0;
}
' file
  • 纯Awk内置逻辑实现,无需依赖外部工具
  • 直接修改对应字段后打印整行,输出格式和输入一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 12:05:13