2つの値ごとに単一の特定の列を複数の列に分割する

2つの値ごとに単一の特定の列を複数の列に分割する

5つのフィールド(5番目のフィールド幅= 200000値[0と1])を持つ遺伝子型ファイルがあります。

MA,30009,4,4,000010000111101011111000110100000000 .......
ME,30067,3,2,000010000111101011111000110100000000 .......
MI,30032,7,8,000010000111101011111000110100000000 .......

最後のフィールドを2つの値ごとに複数の列に分割したい(ncol = 100000)。出力が次のようになります。

MA,30009,4,4,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00 .......
ME,30067,3,2,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00 .......
MI,30032,7,8,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00 .......

え?世話をする医者? sed?

助けが必要ですか?事前にありがとう

答え1

awk 'BEGIN{FS=OFS=","}{gsub(/../,"&,",$NF)}1' file
  • BEGIN{FS=OFS=","}フィールド区切り記号をに設定します,
  • {gsub(/../,"&,",$NF)},最後のフィールド()$NFで2文字ごとに追加されます。
  • 1結果行を印刷します。

結果:

MA,30009,4,4,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00,

上記のコマンドで生成された末尾のカンマを削除するには、アドインを使用してsub削除します。

awk 'BEGIN{FS=OFS=","}{gsub(/../,"&,",$NF);sub(/,$/,"",$NF)}1' file
MA,30009,4,4,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00

答え2

ループでSedを使用できます。

$ sed -E -e :a -e 's/(,[^,]{2})([^,]{1,})$/\1,\2/;ta' file
MA,30009,4,4,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
ME,30067,3,2,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
MI,30032,7,8,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00

(最初から始めて逆さまに作業するよりきれいな方法があると思います$が、完全に確信することはできません。)(拡張正規表現)パターン-Eは必要ありません。単にエスケープを単純化するだけです。

またはPerlを使用してください。

$ perl -F, -lne '$last = pop @F; print join ",", @F, $last =~ m/(..)/g' file
MA,30009,4,4,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
ME,30067,3,2,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
MI,30032,7,8,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00

答え3

GNU awk 最後のフィールドを2番目のフィールドにマージし、フィールド数を減らします。

gawk -F ',' -v OFS="," '{
  $4 = $4 gensub(/../, ",&", "g", $5)
}NF--' file

awkを使う

awk '
  BEGIN { OFS = FS = "," }
  gsub(/../, FS "&", $5) {
    print $1, $2, $3, $4 $5
  }
' file

拡張モードを備えたGNU sed

sed -Ee '
  s/,/\n/4;ta
  :a
    s/\n,/,/;t
    s/..(,..)*$/,&/
  ta
' file

Perlは5番目のフィールドを一度に2文字ずつ解凍します。

perl -F, -lape '$_ = join ",", @F[0..3], unpack "(A2)*", $F[4]' file 

Perlを使用する別の方法

perl -F, -lane 'print reverse pop(@F) =~ s/(..)/,$1/gr, join ",", @F' file
perl -lpe 's/^.*[^,]\K,(.*)/$1 =~ s|(..)|,$1|gr/e' file

rhs で posix sed(\n) を使用することは象徴的です。エスケープされた改行に置き換えます)

sed -e '
  s/,/\n/4;h;s/\n.*//;x
  s/.*\n//;s/../,&/g;H;x
  s/\n//
' file

関連情報