代码之家  ›  专栏  ›  技术社区  ›  pedro

使用条件反转特定字段中的字符串

  •  -1
  • pedro  · 技术社区  · 2 年前

    我有这个文件:

    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
    

    我需要 tr reverse 字段$4和$5仅当 $2==rev

    预期:

    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 -lpe 'if(/rev/) {$rev=/rev/;next}; if ($rev) {$F[4,5]=~tr/ATGC/TACG/; $F[4,5]=reverse $F[4,5]; print "@F"}' file 
    

    我也试着和awk一起去( Execute bash command inside awk and print command output )

    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 回复  |  直到 2 年前
        1
  •  3
  •   zdim    2 年前

    按照问题的尝试:

    perl -w -lanE'
        if ($F[1] eq "rev") { 
            for (@F[3,4]) { tr/ATGC/TACG/; $_ = reverse $_ } 
        } 
        say "@F"
    ' file
    

    可以把它放在一行上(或者复制粘贴到大多数shell中),为了可读性,我把它展开。或者,把它放在一个程序中,特别是如果有更多的事情要做的话。


    编辑--对问题中的代码的评论

    • 让它将输入字符串分解为 @F 数组(“ 自动拆分 “)需要 -a flag

    • 由于您明确地打印了需要使用的内容 -n 标志,不是 -p

    • 行中的字段4和5是数组元素3和4

    • 我认为通过 $F[4,5] 你指的是两个数组元素(应该是3,4)。那么,应该是 @F[3,4] --和 -w flag,作为警告,我们会听到它

    • 更重要的是,我们不能绑定正则表达式或 tr 模式转换为列表,但仅转换为单个标量。为了应用 tr 到多个项目需要对它们进行迭代,如上所述。

    • 循环块中的代码 @F[3,4] 元素在数组的每个元素上运行,并在适当的位置对其进行修改(因为 $_ 只是数组元素的别名),首先使用 tr 然后通过(反转和)分配。所有这些也可以写成

      $_ = reverse tr/ATGC/TACG/r  for @F[3,4];
      

      这个 r 修改器制造 tr 返回更改后的字符串,然后 reverse -ed,然后通过 $_ 它的别名

        2
  •  2
  •   Alex Reynolds    2 年前

    以下是在Python中执行此操作的方法:

    #!/usr/bin/env python
    
    import io
    import sys
    
    RECORDS_STR = '''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'''
    
    '''
    fast pure-Python reverse complement, courtesy of Devon Ryan
    ref. https://bioinformatics.stackexchange.com/a/3585/776
    '''
    DNA_TABLE = str.maketrans("ACTGactg", "TGACtgac")
    def reverse_complement(seq):
        return seq.translate(DNA_TABLE)[::-1]
    
    def main():
        records = io.StringIO(RECORDS_STR) # replace with sys.stdin etc.
        for line in records:
            elems = line.rstrip().split()
            if elems[1] == 'rev':
                elems[3] = reverse_complement(elems[3])
                elems[4] = reverse_complement(elems[4])
            sys.stdout.write('{}\n'.format('\t'.join(elems)))
    
    if __name__ == "__main__":
        main()
    

    输出:

    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