큰 CSV 파일이 있고 이를 더 작은 청크로 분할하고 싶습니다. 다음을 사용하여 CSV 파일을 분할할 수 있다는 것을 알고 있습니다.
split -l 1000000 file.csv new
그 결과 1,000,000개의 행이 있는 부품이 생성됩니다. 그런데 문제는 갈라졌지만 원본도 존재한다는 점이다. 디스크 공간이 부족하기 때문에 원본 파일을 유지하지 않고 CSV를 분할할 수 있는 방법이 있습니까? 도움을 주시면 감사하겠습니다. 미리 감사드립니다.
답변1
stat(1)
한 가지 방법은 GNU 와 GNU를 가정하는 것입니다 truncate(1)
.
#! /bin/sh
lines=1000000
size=$( wc -l "$1" | awk '{print $1}' )
tail=$(( size % lines ))
count=$(( size / lines ))
if [ $tail -ne 0 ]; then
let count++
fi
while [ $count -gt 0 ]; do
start=$(( (count - 1) * lines + 1 ))
fn=$( printf '%s_%05d' "$1" $count )
sed -n $start,\$p <"$1" >"$fn"
size_last=$( stat -c %s "$fn" )
truncate -s -$size_last "$1"
let count--
done
GNU가 없으면 coreutils
Perl에서도 같은 일을 할 수 있습니다.
lines
원본 파일은 이 과정에서 손실되므로 먼저 일부 작은 파일(예: 100으로 설정) 에 대해 위의 내용을 테스트하는 것이 좋습니다 .
답변2
시스템 메모리가 전체 csv
파일을 저장할 수 있을 만큼 크다면 다음을 시도해 볼 수 있습니다.매우 위험한파일을 임시 파일 시스템(예: RAM의 가상 하드 드라이브)에 배치한 다음 거기에서 하드 드라이브로 분할하기 시작하는 방법입니다.
PC의 전원이 꺼지면 파일은 tmpfs
여기에 있습니다.데이터가 손실됩니다! 당신을 불행하게 만드는 것은 아주 아주 쉽습니다.
일반적으로 이미 거기에 있어야 합니다. a가 에 설치된 것으로 나열되어 있는지 /dev/shm
다시 확인한 후 다음을 수행하십시오 .mount | grep shm
tmpfs
/dev/shm
mv file /dev/shm
split -l 1000000 /dev/shm/file /path/to/split/directory/
나는 메모리 사용량에 익숙하지 않기 때문에 파일 크기 외에 얼마나 많은 추가 메모리가 필요한지 모르지만 split
분할하는 행이 최소한 백만 개라고 가정합니다.
다시데이터 손실에 대비하세요단순한 정전 또는 예상치 못한 상황.
추신: 임시 파일 시스템으로 사용할 수 있는 USB 플래시 드라이브가 있을 수도 있습니다. 덜 위험하지만 속도가 느립니다.
답변3
CSV 필드의 순서를 바꿀 수 있는 경우 다음을 시도해 볼 수 있습니다.
SIZ=$(stat -c %s input)
tac input |\
(
IFS=""
while read -r LINE
do
ADJ=${#LINE}
SIZ=$(( (SIZ-ADJ-1) ))
truncate -s $SIZ input
echo "$LINE"
done
) |\
split -l 10 - output
또한 일반 명령보다 실행하는 데 시간이 더 걸리지 split
만 너무 길지는 않을 것입니다.
이는 실제로 디스크 공간을 절약하고 시작 파일이 사용 가능한 디스크 공간의 거의 100%를 차지하는 경우에도 작동합니다.
파일 이름을 변경하고 -l 10
매개변수를 split
.