Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于AWK创建反向补码序列_Python_Awk - Fatal编程技术网

Python 基于AWK创建反向补码序列

Python 基于AWK创建反向补码序列,python,awk,Python,Awk,亲爱的stackoverflow用户: 我有如下选项卡sep数据: head -4 input.tsv seq A C change seq T A ok seq C C change seq AC CCT change 我需要在awk中创建反向补码函数,这样做 head -4 output.tsv seq T G change seq T A ok seq G G change seq GT AGG change aw

亲爱的stackoverflow用户:

我有如下选项卡sep数据:

head -4 input.tsv

seq A      C change
seq T      A ok
seq C      C change
seq AC   CCT change
我需要在awk中创建反向补码函数,这样做

head -4 output.tsv

seq T      G change
seq T      A ok
seq G      G change
seq GT   AGG change
awk 'BEGIN {c["A"] = "T"; c["C"] = "G"; c["G"] = "C"; c["T"] = "A" }{OFS="\t"}
function revcomp(   i, o) {
    o = ""
    for(i = length; i > 0; i--)
        o = o c[substr($0, i, 1)]
    return(o)
}
{

if($4 == "change"){$2 = revcom(); $3 = revcom()} print $0; else print $0}' input
所以,如果第四列标记为“change”,我需要创建反向补码序列

提示-在bash中执行相同的操作,例如
tr
bash此任务的一行代码是:

echo "ACCGA" | rev | tr "ATGC" "TACG"
A => T
C => G
G => C
T => A
ACCATG => CATGGT
我被试过这样的事

head -4 output.tsv

seq T      G change
seq T      A ok
seq G      G change
seq GT   AGG change
awk 'BEGIN {c["A"] = "T"; c["C"] = "G"; c["G"] = "C"; c["T"] = "A" }{OFS="\t"}
function revcomp(   i, o) {
    o = ""
    for(i = length; i > 0; i--)
        o = o c[substr($0, i, 1)]
    return(o)
}
{

if($4 == "change"){$2 = revcom(); $3 = revcom()} print $0; else print $0}' input
生物反向序列平均值:

echo "ACCGA" | rev | tr "ATGC" "TACG"
A => T
C => G
G => C
T => A
ACCATG => CATGGT
和反向补码的意思是:

echo "ACCGA" | rev | tr "ATGC" "TACG"
A => T
C => G
G => C
T => A
ACCATG => CATGGT

编辑:任何仅供教育的人都可以在python中共享此解决方案。

请尝试以下内容,并使用显示的示例编写和测试(在GNU
awk
中)

awk'
开始{
标签[“A”]=“T”
标签[“C”]=“G”
标签[“G”]=“C”
标签[“T”]=“A”
}
函数cVal(字段){
删除数组
num=拆分($field,array,“”)
对于(k=1;k,只需稍微修改一下尝试,您就可以执行以下操作

function revcomp(arg) {
    o = ""
    for(i = length(arg); i > 0; i--)
        o = o c[substr(arg, i, 1)]
    return(o)
}

BEGIN {c["A"] = "T"; c["C"] = "G"; c["G"] = "C"; c["T"] = "A" ; OFS="\t"}

{
    if($4 == "change") {
        $2 = revcomp($2); 
        $3 = revcomp($3)
    } 
}1
这里的关键是使用函数
revcomp
将参数作为列值,并通过从末尾迭代对其进行操作。您以前在整行
$0
,即
substr($0,i,1)
,这将导致对数组
c
进行大量异常查找

我还随意更改了函数的原型
revcomp
,以获取输入字符串并返回反向字符串。因为我不确定您在最初尝试中打算如何使用

如果您打算在较大脚本的一部分中使用上述内容,我建议将上述整个代码放在脚本文件中,将she bang解释器设置为
#!/usr/bin/awk-f
,并以
awk-f script.awk input.tsv
的形式运行脚本

awk
中实现的粗糙bash版本如下所示。请注意,它不是干净的,也不是推荐的方法。请参阅

与前面一样,将函数调用为
$2=revcomp\u bash($2)
$3=revcomp\u bash($3)


您的整个代码都讲GNU
awk
-ism,因此不想将其转换为与POSIX兼容的代码。您可以使用带有空的反限制器的
split()
,而不是
length()
,但是POSIX规范很高兴地说“空字符串作为fs值的效果是未指定的。”对于这个特定的应用程序来说效率有点低,因为它在每次调用
tr()
时都会创建映射数组,并在
tr()
中执行相同的循环,然后在
rev()
中再次执行相同的循环,但我想展示一下如何编写独立的
tr()
rev()
功能强大,而且速度可能足以满足您的需求:

$ cat tst.awk
BEGIN { FS=OFS="\t" }
$4 == "change" {
    for ( i=2; i<=3; i++) {
        $i = rev(tr($i,"ACGT","TGCA"))
    }
}
{ print }

function tr(instr,old,new,      outstr,pos,map) {
    for (pos=1; pos<=length(old); pos++) {
        map[substr(old,pos,1)] = substr(new,pos,1)
    }
    for (pos=1; pos<=length(instr); pos++) {
        outstr = outstr map[substr(instr,pos,1)]
    }
    return outstr
}

function rev(instr,     outstr,pos) {
    for (pos=1; pos<=length(instr); pos++) {
        outstr = substr(instr,pos,1) outstr
    }
    return outstr
}

如果您对
perl
没有异议:

$ perl -F'\t' -lane 'if($F[3] eq "change") {
                     $F[1] = (reverse $F[1] =~ tr/ATGC/TACG/r);
                     $F[2] = (reverse $F[2] =~ tr/ATGC/TACG/r) }
                     print join "\t", @F' ip.txt
seq T   G   change
seq T   A   ok
seq G   G   change
seq GT  AGG change
也可以使用,但这不是特定于列的,将更改
ATCG
字符的任何序列:

perl -lpe 's/\t\K[ATCG]++(?=.*\tchange$)/reverse $&=~tr|ATGC|TACG|r/ge'

OP表示如果第4列标记为“更改”@oguzismail,现在做了更改,谢谢你让我知道。@RavinderSingh13谢谢你非常及时的回答-我将尝试测试你的解决方案!@Geroge,我当然也在这里添加了详细的级别解释,以防我在这里遇到任何疑问。谢谢你的回答。可能是愚蠢的问题,但我没有看到任何“awk”关于脚本的开始?@ Geroge:只使用“代码> AWK……”输入的全部片段。TSV 这是绝对完美的解决方案,看起来非常有效!非常感谢!!您的代码是POSIX兼容的,没有GNUISS。您应该考虑的一个调整是:<代码> ReVCOMP(ARG)< /代码>应该是代码> ReVCOMP(ARG,I,O)
因此,
i
o
是函数局部变量,与代码中其他地方或第二次调用该代码时的值无关。如果这样做,则不需要
o=”“