열에 따라 파일을 여러 개의 작은 파일로 분할

열에 따라 파일을 여러 개의 작은 파일로 분할

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

처음 세 개의 열을 선택합니다.

문자 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>

관련 정보