特定の文字列に基づいて列を複数の列に分割する

特定の文字列に基づいて列を複数の列に分割する

独自の列を含むファイルがあり、この列を特定の文字列(chr)に基づいて複数の列に分割したいと思います。

入力は次のとおりです。

chr10:127293562-127293909
BRUNOL4(Hs/Mm)
CPEB4(Hs/Mm)
CUG-BP(Hs/Mm)
DAZAP1(Hs/Mm)
ENOX1(Hs/Mm)
FMR1(Hs/Mm)
chr11:49214073-49214804
BRUNOL4(Hs/Mm)
BRUNOL5(Hs/Mm)
CPEB2(Hs/Mm)
CPEB4(Hs/Mm)
CUG-BP(Hs/Mm)
HNRNPC(Hs/Mm)

出力は次のようになります。

chr10:127293562-127293909  chr11:49214073-49214804
BRUNOL4(Hs/Mm)             BRUNOL4(Hs/Mm)
CPEB4(Hs/Mm)               BRUNOL5(Hs/Mm)    
CUG-BP(Hs/Mm)              CPEB2(Hs/Mm)
DAZAP1(Hs/Mm)              CPEB4(Hs/Mm)    
ENOX1(Hs/Mm)               CUG-BP(Hs/Mm)
FMR1(Hs/Mm)                HNRNPC(Hs/Mm)

どんなアイデアでも大いに感謝します。

答え1

awk '/^chr/{i++} 
           {print > "_aux" i }
       END {system( "paste _aux* | column -tn; rm _aux*")}' file
  • 最初の2行(print > "_aux" i)は入力をファイルセットに分割します_aux1... _auxn(各ファイル= 1列)
  • 最後に、paste _aux* | column -tnさまざまなセクションを貼り付けてフォーマットします。

このソリューションは複数の列を処理できることを願っています。

答え2

これは典型的なawk問題です:

#!/usr/bin/awk -f
BEGIN{ col = -1; l = 0; r = 0; width = 0; }
/^chr[0-9]+:/ {
        ++col;
}
{
        if ( col == 0 ) {
                L[l++] = $0;
        } else {
                R[r++] = $0;
        }
        if ( length ($0) > width ) {
                width = length ($0) ;
        }
}
END {
        for ( i = 0; i < l; ++i ) {
                printf "%-*s %s\n", width, L[i], R[i];
        }
}

スクリプト名を「foo」と指定し、実行可能にし、データをパイプで連結します。

./foo < foo.in

与える

chr10:127293562-127293909 chr11:49214073-49214804
BRUNOL4(Hs/Mm)            BRUNOL4(Hs/Mm)
CPEB4(Hs/Mm)              BRUNOL5(Hs/Mm)
CUG-BP(Hs/Mm)             CPEB2(Hs/Mm)
DAZAP1(Hs/Mm)             CPEB4(Hs/Mm)
ENOX1(Hs/Mm)              CUG-BP(Hs/Mm)
FMR1(Hs/Mm)               HNRNPC(Hs/Mm)

左/右の列に同じ数の項目があり、2つの列しかないとします。 awkには1次元配列しかありません。問題がより多くの列(たとえば、任意の数)を必要とする場合、awk(または好ましくはPerl)の解決策はより複雑になります。これには、どうすればよいかについてより明確な質問が必要です。それ

関連情報