当我用 awk 找到特殊字符时只编辑特定的行

Edit only specific lines when I find special character with awk

我有这样的文件:

>AX-89948491-minus
CTAACACATTTAGTAGATT
>AX-89940152-plus
cgtcattcagggcaggtggggcaaaA
>AX-89922107-plus
TTATAACTTGTGTATGCTCTCAGGCT

当行以“>”开头并包含“减号”时,我需要反转 (rev) 并翻译 (tr) 接下来的行。我应该得到:

>AX-89948491-minus
AATCTACTAAATGTGTTAG
>AX-89940152-plus
cgtcattcagggcaggtggggcaaaA
>AX-89922107-plus
TTATAACTTGTGTATGCTCTCAGGCT

我想用awk。我试过了,但它不起作用..

awk '{if(NR%2==1~/"plus"/){print;getline;print} else if (NR%2==1~/"minus"/){system("echo "[=12=]" | rev | tr ATCGatcg TAGCtagc")} else {print;getline;print}}' file

有什么帮助吗?

这个 gnu-awk 应该适合你:

awk '
p {
   cmd = "rev <<< 7" [=10=] "7 | tr ATCGatcg TAGCtagc"
   if ((cmd |& getline var) > 0)
      [=10=] = var
}
{
   p = /^>/ && /-minus/
} 1' file

>AX-89948491-minus
AATCTACTAAATGTGTTAG
>AX-89940152-plus
cgtcattcagggcaggtggggcaaaA
>AX-89922107-plus
TTATAACTTGTGTATGCTCTCAGGCT

Awk 是一种处理文本的工具,而不是一种对其他工具的调用进行排序的工具。后者是 shell 的用途。有时您需要从 awk 调用其他工具,但当它只是简单的文本操作(如您想要的那样反转和翻译字符串中的字符)时则不需要。

在每个 Unix 机器上的任何 shell 中使用任何 awk 而不产生子shell 每个目标输入行一次调用其他 Unix 工具(包括 non-POSIX-defined rev 在某些 Unix 机器上不存在):

$ cat tst.awk
BEGIN {
    split("ATCGatcg TAGCtagc",tmp)
    for (i=1; i<=length(tmp[1]); i++) {
        tr[substr(tmp[1],i,1)] = substr(tmp[2],i,1)
    }
}
f {
    out = ""
    for (i=1; i<=length([=10=]); i++) {
        char = substr([=10=],i,1)
        out = (char in tr ? tr[char] : char) out
    }
    [=10=] = out
    f = 0
}
/^>.*minus/ { f=1 }
{ print }

$ awk -f tst.awk file
>AX-89948491-minus
AATCTACTAAATGTGTTAG
>AX-89940152-plus
cgtcattcagggcaggtggggcaaaA
>AX-89922107-plus
TTATAACTTGTGTATGCTCTCAGGCT

我会使用 perl,因为它内置了 reversetr 函数:

perl -lpe '
    if (/^>/) {$rev = /minus/; next}
    if ($rev) {$_ = reverse; tr/ATCGatcg/TAGCtagc/}
' file
>AX-89948491-minus
AATCTACTAAATGTGTTAG
>AX-89940152-plus
cgtcattcagggcaggtggggcaaaA
>AX-89922107-plus
TTATAACTTGTGTATGCTCTCAGGCT