将一个文件按照列分成几个小文件

将一个文件按照列分成几个小文件

我有一个数据文件,它可以有N行,每行由M个由空格分隔的元素组成。目前,我想将每一行分成几个段。换句话说,假设段数为3;那么原始文件将被分成3个文件,每个文件有N行,每行有M/3个元素。除了编写 C++ 或 Java 程序之外,是否有任何有效的方法可以在 Unix/Linux 上完成此任务?

答案1

这可满足同一文件中不同数量的字段的需求,并且最后一个段仅部分填充,即字段少于指定的字段(每个段)。
但请注意,如果行中的字段数导致段数少于指定的段数,则不会针对这些不足的段向输出文件写入任何内容。

awk -v 'ncol=5' -v 'pfix=file' '{
    fldn = 0
    sfix = 1
    segs = NF/ncol
    # round up if number of field is not evenly divisible by number of columns    
    segs = (segs == int(segs)) ?segs :int(segs)+1   
    while (fldn != NF) {
        fmod = (++fldn) % ncol
        printf "%s%s", dlim, $(fldn) >> pfix sfix 
        if (fmod == 1 ) { dlim = " " }
        if ((fmod==0 ) || (fldn==NF))  { 
            printf "\n" >> pfix sfix 
            dlim = ""; sfix++ 
        }
    } 
}' infile

答案2

如果您的文件是干净的,我建议使用标准应用程序cut

cut有你至少应该知道的三个标志

  • -d 定义分隔符(TAB 是默认值
  • -f 选择字段
  • -c 选择字符范围

您可以选择使用组合 -d -f 或 -c 如果您的文件不是制表符分隔的,而是由空格很好地分隔的,您可以这样做

cut -d' ' -f1-3

选择前三列。

如果你想选择第 4 列,即字符 25 和 36 之间,你可以这样做

cut -c25-36

答案3

这是你想要的?

awk '{ print $1 $2 $3 > file1; print $4 $5 $6 > file2; print $7 $8 $9 > file3 }' originalfile

或者你想要一些更通用的东西?

awk -v 'n=3' -v 'prefix=pref' '{
    for (i = 0; i < n; i++) {
        for (j = 0; j < NF / n; j++) {
            printf("%s ", $(i + j + 1)) > prefix i
        }
        printf("\n") > prefix i
    }
}' originalfile

注意:这依赖于所有行具有相同列数的假设。

答案4

sep_file.ksh

#!/bin/ksh

FILENAME=$1
SEG=$2

SEG_NO=1

while [[ $SEG_NO -le $SEG ]]
do
  awk '{CL=NF/'"$SEG"';CL=(CL==int(CL)?CL:int(CL)+1);LS=(('"$SEG_NO"'-1)*CL)+1;LE=LS+CL-1;if(LE>NF)LE=NF;for(i=LS;i<=LE;i++)printf("%s ",$i);printf("\n")}' $FILENAME > ${FILENAME}_$SEG_NO
  SEG_NO=`echo "$SEG_NO + 1"|bc`
done

用法:./sep_file.ksh <file_name_to_read> <no_of_segments>

相关内容