如何将一大行字符分割成列数相等的几行?

如何将一大行字符分割成列数相等的几行?

如果数据文件如下所示:

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

一种选择是使用珀尔 正则表达式, 像这样:

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

正则表达式表示找到一个或多个非空格后跟一个或多个空格,并将前 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

如果您需要的只是四列:

$ 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*$n2*$n - 1等等,只要$n计数器小于表上的字段总数。线。这假设所有数据都在一行上,后续行将被视为单独的数据集。

相关内容