大きな文字列を同じ数の列を持つ複数行に分割するには?

大きな文字列を同じ数の列を持つ複数行に分割するには?

データファイルが次の場合:

snp200 snp1 snp100 snp32 1 1 0 2 0 0 0 2 2 2 2 1...

snp..が完了したら、列名として使用し、残りの数字を均等に分割します(各行の合計数は最初の行の列名の数と等しくなければなりません)。どのように行を分割し、各行ごとに次の行に入れます。この小さな例には4つの列名があるため、残りの4行には4桁の出力が必要です。

snp200 snp1 snp100 snp32
1 1 0 2
0 0 0 2
2 2 2 1 
...

実際のデータが非常に大きいことを考慮すると(列名が32000以上)、提案がある場合

答え1

1つのオプションは、次を使用することです。真珠 正規表現、このように:

cat in.txt | perl -pe 's/(([^ ]+ +){4})/$1\n/g' > out.txt

正規表現は、1つ以上の空白以外の項目と1つ以上の空白を検索し、最初の2つを4つのグループにグループ化してから、各一致の後に新しい行を追加することを意味します。

テストケース:

echo "snp200 snp1 snp100 snp32 1 13454356 0 2 0 0 0 2 2 2 2 1" | perl -pe 's/(([^ ]+ +){4})/$1\n/g'
snp200 snp1 snp100 snp32 
1 13454356 0 2 
0 0 0 2 
2 2 2 1

答え2

BSDの使用rs(1):

rs 0 4 <data.txt >out.txt

答え3

4つの列のみが必要な場合:

$ cat data.file | tr ' ' '\n' | columns -w 10 -c 4

snp200    snp1      snp100    snp32
1         1         0         2
0         0         0         2
2         2         2         1

答え4

名前付きタグの数が異なる場合は、まずタグ数を数えることをお勧めします。 Perlでは、次のようになります。

perl -lane '
   $n++ while $F[$n] =~ /^[a-z]/; 
   do { 
     print join(" ", @F[$_*$n .. $_*$n + $n - 1])
   } while (++$_*$n <= $#F)' < input

まず、$n文字で始まる各フィールドが増加して名前付きフィールドの数を提供し、カウンタが合計フィールド数より小さい限り空白、フィールドが に結合された後0*$n1*$n - 1結合1*$nされる2*$n - 1式で印刷が繰り返されます。$nテーブルのフィールドです。ワイヤー。これは、すべてのデータが1つの行にあり、その後の行が別々のデータセットとして扱われると仮定します。

関連情報