1

输入:

rs001 A C T G C G T T
rs002 C C T T G G A A

输出1:

rs001 AC TG CG TT
rs002 CC TT GG AA

输出2:

rs001 1 1 1 2
rs002 2 2 2 2

好的,所以基本上我想将任何两个相似的核苷酸(如 AA、CC、TT 或 GG)替换为 2,并将任何两个不同的核苷酸(如 AT、TA、CG、.. 等)替换为 1,同时考虑到输入应该是首先转换为 out1,然后转换为 out2。此外,我们在每一行中有很多字段(如 200 列),所以这里需要循环。

这是我尝试过的:

cat input | awk '{ for (x = 2; x <= NF; x = x+2) print $x$(x+1) }'

结果太奇怪了,谁能告诉我为什么我出不去1?!我在 awk 循环中犯了什么错误?

提前致谢

4

4 回答 4

4

为了第一,

sed 's/ \([ACGT]\) / \1/g' input >out1

这将在每隔一个核之后删除空间。它匹配两侧有空格的核苷酸;下一场比赛将从上一场比赛结束的地方开始。

对于第二个,

sed 's/\([ACGT]\)\1/2/g;s/[ACGT][ACGT]/1/g' out1 >out2

这会将两个相邻的相同字母替换为 2,然后将任何剩余的相邻两个字母替换为 1。

这假设你有 Linux;其他sed方言可能需要稍作修改。

于 2012-11-01T15:10:16.627 回答
2
awk '{
   out1 = out2 = $1
   for (i=2;i<=NF;i+=2) {
      out1 = out1 FS $i $(i+1)
      out2 = out2 FS ($i == $(i+1) ? 2 : 1)
   }
   print out1 > "out1"
   print out2 > "out2"
}' input
于 2012-11-01T15:15:19.693 回答
1

以下是修复awk脚本以获取输出 1 的方法:

awk '{ printf "%s ", $1; for (x = 2; x <= NF; x = x + 2) {printf "%s%s ", $x, $(x+1)} printf "\n"}' input

print默认情况下在末尾添加一个新行,因此您必须使用格式化字符串printf来指定您想要新行的确切位置。

(也在开始处添加printf "%s ", $1;以在每行开头打印标题)

编辑:Triplee 的解决方案看起来比我的要优雅得多——你应该放弃 awk 并选择他的 =)

于 2012-11-01T15:09:33.900 回答
0

这可能对您有用(GNU sed):

sed -re 's/ (.) / \1/g;w out1' -e 's/([ACTG])\1/2/g;s/[ACTG]./1/g' file >out2
于 2012-11-02T09:54:05.570 回答