当我用 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,因为它内置了 reverse
和 tr
函数:
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
我有这样的文件:
>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,因为它内置了 reverse
和 tr
函数:
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