给定文件test.txt
,其中包含以下内容:
ABC DEF GATTAG GHK
ABC DEF GGCGTC GHK
ABC DEF AATTCC GHK
需要修改第3列,以便字符串是反向补码。部分可以使用bash命令完成:
cat test.txt | cut -f3 | rev | tr ATGC TACG
CTAATC
GACGCC
GGAATT
如何使用awk
实现? (有一个更大的awk脚本用于处理文件,此函数将添加到该文件中。)
可能的一种方法是在rev | tr ATGC TACG
内执行awk
,类似于:
awk '{newVar=system("rev | tr ATGC TACG"$3); print $1 $2 newVar $4}' test.txt
但是,这个和各种类似的版本不起作用。有人可以指出什么是不正确的吗?
答案 0 :(得分:3)
只需在awk中进行字符串反转和翻译:
$ awk '
BEGIN {
old="ATGC"
new="TACG"
for (i=1;i<=length(old);i++) {
tr[substr(old,i,1)] = substr(new,i,1)
}
}
{
newVar=""
for (i=1;i<=length($3);i++) {
char = substr($3,i,1)
newVar = (char in tr ? tr[char] : char) newVar
}
print $1, $2, newVar, $4
}
' file
ABC DEF CTAATC GHK
ABC DEF GACGCC GHK
ABC DEF GGAATT GHK
如果你真的觉得需要从awk调用外部工具并阅读结果,那就是:
$ awk '
{
cmd="echo \047" $3 "\047 | rev | tr \047ATGC\047 \047TACG\047"
newVar=((cmd | getline line) > 0 ? line : "failed")
close(cmd)
print $1, $2, newVar, $4
}
' file
ABC DEF CTAATC GHK
ABC DEF GACGCC GHK
ABC DEF GGAATT GHK
但是你应该期待这样做会带来显着的性能影响,并且还会看到获取线警告:http://awk.freeshell.org/AllAboutGetline。
答案 1 :(得分:0)
如果perl
没问题:
$ perl -lane '$F[2]=~tr/ATGC/TACG/; $F[2]=reverse $F[2]; print join " ",@F' test.txt
ABC DEF CTAATC GHK
ABC DEF GACGCC GHK
ABC DEF GGAATT GHK
-a
选项会将空格分割并保存到@F
数组
perl -i -lane
进行内部编辑$F[2]=~tr/ATGC/TACG/
仅将tr
用于第3列$F[2]=reverse $F[2]
反转第3列的字符串print join " ",@F
以空格作为分隔符
也可以写成
perl -lane '$F[2]=reverse $F[2]=~tr/ATGC/TACG/r; print join " ",@F' test.txt
或在替换部分中使用Perl代码
perl -pe 's/^(\H+\h+){2}\K\H+/reverse $&=~tr|ATGC|TACG|r/e' test.txt