将分离的字符重新格式化为夫妻

时间:2012-11-01 15:01:37

标签: perl sed awk

输入:

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

OUT1:

rs001 AC TG CG TT
rs002 CC TT GG AA

out2:

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 个答案:

答案 0 :(得分: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方言可能需要稍作修改。

答案 1 :(得分: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

答案 2 :(得分: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并选择他的=)

答案 3 :(得分:0)

这可能适合你(GNU sed):

sed -re 's/ (.) / \1/g;w out1' -e 's/([ACTG])\1/2/g;s/[ACTG]./1/g' file >out2