根据特定字符串将一列拆分为多列

根据特定字符串将一列拆分为多列

我有一个包含唯一列的文件,我想根据特定字符串 (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(每个文件 = 一列)
  • 最后,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)

假设左/右列具有相同数量的项目,并且您只有两列。 awk 只有一维数组。如果您的问题需要更多列(例如,任意数量),则 awk(或最好是 perl)中的解决方案会更复杂。为此,您需要一个更清晰的问题来解决如何做

相关内容