1

入力:

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

わかりましたので、基本的には、入力が最初に out1 に変換され、次に out2 に変換されます。また、各行には非常に多くのフィールド (200 列など) があるため、ここでループが必要です。

これは私が試したものです:

cat input | awk '{ for (x = 2; x <= NF; x = x+2) print $x$(x+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 つの同一の文字が 2 に置き換えられ、残りの隣接する 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 に答える