Как разбить файлы CSV по количеству указанных строк?

84

У меня есть файл CSV (около 10 000 строк; каждая строка имеет 300 столбцов), хранящиеся на сервере LINUX. Я хочу разбить этот CSV-файл на 500 CSV-файлов по 20 записей в каждом. (У каждого из них тот же заголовок 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
Что это за символ новой строки? Он все еще работает для меня в UTF-8, не уверен, поможет ли это.
owyongsk
3
@ shashi009: Предположим, исходный файл называется file.txt. 1: пропустить первую строку, затем передать оставшуюся часть файла по конвейеру split, который разбивается на новые файлы каждые 20 строк длиной, с префиксом split_2: итерация по новым файлам split_ *, сохраняя каждое имя в переменной file, по одному 3: для каждого ... 4: записать первую строку (заголовки столбцов) из нашего исходного файла в tmp_file 5: добавить файл с разделением на 20 строк в tmp_file 6: перезаписать старый файл split_ * новым tmp_file, чтобы сохранить заголовки столбцов
Дэвид
1
Добавление заголовка с помощью echo -e "$HEADER\n$(cat $i)" > $iизлишне неэффективно. Я заменил его на sed -i -e "1i$HEADER" "$i".
Филипп Моерс
150

Используйте команду разделения Linux:

split -l 20 file.txt new    

Разделите файл «file.txt» на файлы, начинающиеся с имени «новый», каждый из которых содержит 20 строк текста.

Введите man splitв командной строке Unix для получения дополнительной информации. Однако вам нужно сначала удалить заголовок из file.txt (например, используя tailкоманду), а затем снова добавить его в каждый из разделенных файлов.

Джеймс Кинг
источник
Как я могу пропустить первую строку (заголовок) file.txt?
forkfork
используйте, wc -lчтобы получить количество строк, затем возьмите это значение, вычтите 1 (предположим, получилось wc -l50) и затем запустите tail -n 49(в этом примере), чтобы получить все, кроме строки заголовка. Обратите внимание, что wc -lучитываются символы <newline>, поэтому, если последняя строка не заканчивается символом новой строки, вы будете отключены на 1 в вашем количестве строк.
Лукас Робертс
4
@lucas, tail -n +2 напечатает все строки, кроме первой.
Джеймс Кинг,
@JamesKing, +1 и спасибо! Я должен прочитать документацию более внимательно :)
Лукас Робертс
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 имя_файла.csv часть_файла

Коралловый
источник
это работает абсолютно нормально! Есть ли способ ограничить количество создаваемых мной файлов строк в 10000? Скажем, я просто хочу, чтобы первые 200000 строк были разделены на файлы csv по 10 тыс. Строк, а остальные игнорировались.
Pronomita Dey
1
@Pronomitahead -200000 file.csv | split -l 10000 - new_
boloyao
2
У меня был файл CSV размером 13 ГБ с поврежденной строкой примерно в строке ~ 69 000 000. Он блокировал импорт в bigquery. Это позволило мне рекурсивно разделить его, пока я не смог изолировать строку и исправить ее. Ни одно другое решение не было столь эффективным в обработке больших файлов без остановки сервера или блокировки. На разбиение файла на 5 000 000 строк потребовалось около 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
Марк Сетчелл
источник
Это создало файлы, но вкладки (я имею в виду \ t) были заменены пробелами, а в моих файлах CSV в качестве разделителя использовался \ t
AmineG
Это можно немного улучшить, добавив номера в поля, чтобы файлы отображались последовательно автоматически. Заменив $ {n} на $ (printf "% 05d \ n" $ n)
Финеас Дашевский
4
Строка заголовка дублируется в первом файле.
Juha Palomäki
12

У меня есть однострочный ответ (этот пример дает вам 999 строк данных и одну строку заголовка на файл)

cat bigFile.csv | parallel --header : --pipe -N999 'cat >file_{#}.csv'

https://stackoverflow.com/a/53062251/401226

Тим Ричардсон
источник