지정된 행 수에 따라 CSV 파일을 분할하는 방법은 무엇입니까?


84

LINUX 서버에 CSV 파일 (약 10,000 행, 각 행마다 300 열)이 저장되어 있습니다. 이 CSV 파일을 각각 20 개 레코드의 500 개 CSV 파일로 나누고 싶습니다. (각각 원본 CSV에있는 것과 동일한 CSV 헤더를 가짐)

이 변환을 돕는 Linux 명령이 있습니까?


1
이것은 실제로 작동하지만 첫 번째 파일의 헤더가 복제되어 첫 번째 csv 파일 2 헤더를 제공합니다.
rickman


답변:


79

그것을 함수로 만들었습니다. 이제 전화 할 수 있습니다.splitCsv <Filename> [chunkSize]

splitCsv() {
    HEADER=$(head -1 $1)
    if [ -n "$2" ]; then
        CHUNK=$2
    else 
        CHUNK=1000
    fi
    tail -n +2 $1 | split -l $CHUNK - $1_split_
    for i in $1_split_*; do
        sed -i -e "1i$HEADER" "$i"
    done
}

위치 : http://edmondscommerce.github.io/linux/linux-split-file-eg-csv-and-keep-header-row.html


1
작동 방식을 설명해 주시겠습니까? 원본 게시물을 확인했지만 설명도없고 댓글 게시 옵션도 없습니다.
shashi009

6
CSV의 셀에 줄 바꿈이 포함되어 있으면 어떻게됩니까?
Ondřej Hlaváček 2011

어떤 종류의 개행 문자입니까? UTF-8에서 여전히 작동하지만 이것이 도움이되는지 확실하지 않습니다.
owyongsk

3
@ shashi009 : 원본 파일이 file.txt라고 가정합니다. 1 : 첫 번째 줄을 건너 뛰고 나머지 파일을로 파이프합니다.이 파일 split은 접두사 split_2를 사용하여 20 줄씩 새 파일로 분할됩니다 . 새 split_ * 파일을 반복하여 각 이름을 file한 번에 하나씩 변수에 저장합니다. 3 : for each ... 4 : 원본 파일의 첫 번째 줄 (열 헤더)을 tmp_file 5 :에 작성합니다. 5 : 20 줄 분할 파일을 추가합니다 tmp_file . 6 : 이전 split_ * 파일을 new로 덮어 써 tmp_file열 헤더를 유지합니다.
David

1
헤더를 비아 앞에 붙이는 echo -e "$HEADER\n$(cat $i)" > $i것은 불필요하게 중요합니다 . 나는 그것을 sed -i -e "1i$HEADER" "$i".
Philipp Moers

150

Linux split 명령을 사용하십시오.

split -l 20 file.txt new    

"file.txt"파일을 각각 20 줄의 텍스트가 포함 된 "new"이름으로 시작하는 파일로 분할합니다.

man split자세한 내용은 Unix 프롬프트에서 입력 하십시오. 그러나 먼저 file.txt에서 헤더를 제거한 다음 ( tail예 : 명령 사용 ) 각 분할 파일에 다시 추가해야합니다.


file.txt 첫 번째 (헤더) 줄을 어떻게 건너 뛸 수 있습니까?
forkfork

를 사용 wc -l하여 줄 수를 얻은 다음이 값에서 1을 뺀 wc -l다음 tail -n 49(이 예에서 50 을 주었다고 가정 ) 실행 하여 헤더 줄을 제외한 모든 것을 가져옵니다. wc -l<newline> 문자 를 계산하므로 마지막 줄이 줄 바꿈 문자로 끝나지 않으면 줄 수에서 1만큼 떨어져 있습니다.
Lucas Roberts

4
@lucas tail -n +2 는 첫 번째 줄을 제외하고 모든 줄을 인쇄합니다.
James King

@JamesKing, +1 & 감사합니다! 문서를 더 자세히 읽어야합니다. :)
Lucas Roberts

6
새 파일에 ".csv"를 유지하려면 그냥 추가하십시오--additional-suffix=.csv
Cocuba

22

이것은 작동합니다 !!!

file_name= 분할하려는 파일의 이름.
10000= 각 분할 파일에 포함될 행 수
file_part_= 분할 파일 이름의 접두사 (file_part_0, file_part_1, file_part_2..etc 계속됨)

split -d -l 10000 file_name.csv file_part_


이것은 절대적으로 잘 작동합니다! 내가 만드는 10000 개의 행 파일 수를 제한 할 수있는 방법이 있습니까? 처음 200,000 개 행을 10k 행 csv 파일로 나누고 나머지는 무시하고 싶다고 가정 해 보겠습니다.
Pronomita Dey

1
@Pronomitahead -200000 file.csv | split -l 10000 - new_
boloyao

2
약 69,000,000 줄에 손상된 줄이있는 13Gb CSV 파일이 있습니다. 이로 인해 bigquery로 가져 오기가 차단되었습니다. 이를 통해 선을 분리하고 수정할 수있을 때까지 반복적으로 분할 할 수있었습니다. 서버를 중단하거나 사물을 잠그지 않고 대용량 파일을 처리하는 데있어 다른 솔루션은 없었습니다. 파일을 5000000 행 청크로 분할하는 데 약 2 분이 걸렸습니다. 감사!
LP Papillon

13

그러면 모든 파일이 Part1-Part500으로 표시됩니다.

#!/bin/bash
FILENAME=10000.csv
HDR=$(head -1 $FILENAME)   # Pick up CSV header line to apply to each file
split -l 20 $FILENAME xyz  # Split the file into chunks of 20 lines each
n=1
for f in xyz*              # Go through all newly created chunks
do
   echo $HDR > Part${n}    # Write out header to new file called "Part(n)"
   cat $f >> Part${n}      # Add in the 20 lines from the "split" command
   rm $f                   # Remove temporary file
   ((n++))                 # Increment name of output part
done

이는 세퍼레이터로하지만 파일 탭 (I 평균 \ t) 스페이스로 대체하고, 제 CSV 파일 사용한 \ t 생성
AmineG

파일이 자동으로 연속적으로 표시되도록 숫자를 채우면 약간 개선 될 수 있습니다. $와 $ {N}을 교체함으로써 (의 printf를 "% 05D \ n"$ N)
피니 Dashevsky

4
헤더 행은 첫 번째 파일에 중복됩니다.
Juha Palomäki

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.