У меня большой CSV-файл, и я хочу разделить его на небольшие куски. Я знаю, что я могу разделить CSV-файл, используя
split -l 1000000 файл.csv new
, что приводит к тому, что часть имеет строки 1000000.Но проблема в том, что она разделяется, но также существует оригинальная. Поскольку у меня не так много места на диске, есть ли способ разделить CSV, не сохранив исходный? Любая помощь приветствуется. Заранее спасибо.
Если можно изменить порядок полей 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
. Я разместил его так, как тестировал, в файл, содержащий гораздо меньше миллиона строк.
Один из способов сделать это, предполагая GNU stat(1)
и 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.
Если память в вашей системе достаточно велика для хранения всего файла csv
, вы можете попробовать этот очень опасный способ помещения файла во временную файловую систему (т. Е. виртуальный жесткий диск в вашей оперативной памяти), а затем начните разделять его оттуда на жесткий диск.
Обратите внимание, что при выключении ПК, когда файл находится в этом tmpfs
, данные будут потеряны ! Это очень, очень расстраивает вас.
Обычно / dev / shm
уже должен присутствовать, дважды проверьте, если mount | grep shm
перечисляет tmpfs
как смонтированный на / dev / shm
, затем:
mv file /dev/shm
split -l 1000000 /dev/shm/file /path/to/split/directory/
Я не знаю, сколько избыточной памяти вам понадобится помимо файла size, поскольку я не знаком с использованием памяти split
, но я предполагаю, что это будет по крайней мере один миллион строк, которые вы разделяете.
Опять же будьте готовы к потере данных из-за простого отключения электроэнергии или чего-либо неожиданного.
PS: Возможно, у вас есть USB-накопитель для использования в качестве временной файловой системы - менее опасно, но медленнее.