列に従ってファイルを複数の小さなファイルに分割する

列に従ってファイルを複数の小さなファイルに分割する

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あなたが知る必要がある少なくとも3つの兆候があります

  • -d区切り文字を定義します(TABがデフォルト値です)。
  • -f フィールドの選択
  • -c文字範囲の選択

オプションで、-d -f または -c の組み合わせを使用できます。ファイルがタブで区切られていないが空白できれいに区切られている場合にできること

cut -d' ' -f1-3

最初の3つの列を選択します。

文字 25 から 36 の間にある列 4 を選択するには、次のようにします。

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>

関連情報