Разделить файл csv на более мелкие файлы, если целое число найдено в первом столбце

Если что-то пошло не так во время обновления или обновления основной версии, наличие / home на другом разделе позволяет загружать с компакт-диска, а затем полностью стереть и переустановить операционную систему, не теряя ваши данные. Кроме того, это делает возможной множественную загрузку с различными дистрибутивами Linux, некоторым людям нравится оценивать их бок о бок.

2
задан 4 January 2018 в 17:13

6 ответов

Вы можете использовать утилиту csplit для разделения на регулярное выражение, например

csplit -z file.csv '/^[0-9]\+,/' '{*}'
80
42

(подсчет указывает количество символов, выводимых в каждый файл, - вы можете их подавить, добавив -s).

Выходные файлы по умолчанию - xx00, xx01 и т. д. - есть опции для изменения префикса и суффикса, если хотите.

Пример

[F2]
3
ответ дан 22 May 2018 в 15:46
  • 1
    Пожалуйста, поправьте меня, если я ошибаюсь. На мой взгляд, csplit может разделять только 1 файл на 2, он не может разбить файл на несколько файлов. – kashish 4 January 2018 в 17:47
  • 2
    @kashish вы попробовали? он должен разбивать на столько файлов, сколько есть совпадений - я не могу проверить, потому что ваш образец содержит только 2 – steeldriver 4 January 2018 в 17:50
  • 3
    Я пытался. В нем говорится, что csplit: *}: bad repetition count – kashish 4 January 2018 в 17:53
  • 4
    @kashish извините - я не могу воспроизвести эту ошибку. Возможно, вы могли бы обновить свой вопрос с более репрезентативной выборкой ваших входных данных? – steeldriver 4 January 2018 в 19:26

Вы можете использовать утилиту csplit для разделения на регулярное выражение, например

csplit -z file.csv '/^[0-9]\+,/' '{*}' 80 42

(подсчет указывает количество символов, выводимых в каждый файл, - вы можете их подавить, добавив -s).

Выходные файлы по умолчанию - xx00, xx01 и т. д. - есть опции для изменения префикса и суффикса, если хотите.

Пример

[F2]
3
ответ дан 17 July 2018 в 23:53

Вы можете использовать утилиту csplit для разделения на регулярное выражение, например

csplit -z file.csv '/^[0-9]\+,/' '{*}' 80 42

(подсчет указывает количество символов, выводимых в каждый файл, - вы можете их подавить, добавив -s).

Выходные файлы по умолчанию - xx00, xx01 и т. д. - есть опции для изменения префикса и суффикса, если хотите.

Пример

[F2]
3
ответ дан 24 July 2018 в 17:07

Я хотел посмотреть, сколько из этого я мог бы сделать с sed, и мне это удалось сделать довольно много. Мы можем писать файлы с помощью sed с помощью команд w и W, но я не мог придумать способ записи другого файла с каждой итерацией цикла sed, поэтому мне пришлось использовать оболочку петля. sed, вероятно, не тот инструмент, который можно использовать для этой работы, и, вероятно, лучше сделать это с помощью sed. В любом случае, вот что я придумал:

#!/bin/bash
sed ':a;N;s/\n/\x00/; ta' input | sed -r 's/\x00([0-9]+(,|\x00|$))/\n\1/g' > edited
n=0
while [ -s edited ]; do 
    ((n++))
    sed -n '1p' edited > csv-"$n"
    sed -i '1d' edited
done
sed -i 'y/\x00/\n/' csv-*
rm edited

Комментарии

заменяют строки новой строки нулевым символом \x00, используя петлю sed. Это значит, что позже мы можем использовать новые строки как значимые разделители.
sed ':a;N;s/\n/\x00/; ta' input
обрабатывает результат и добавляет новые строки перед целыми числами, которые были в первом поле, и записывает результат в файл, edited
| sed -r 's/\x00([0-9]+(,|\x00|$))/\n\1/g' > edited
инициализирует переменную для увеличения
n=0
, пока edited не пуст,
((n++))
записать первую строку edited в новый файл csv-$n, где $n - текущее значение n
sed -n '1p' edited > csv-"$n"
удалить первую строку из edited
sed -i '1d' edited
, это конец цикла, и поскольку у нас есть только одна строка для каждого файла, который мы хотим записать, это не так медленно, как обработка каждой строки исходного файла в цикле, но тем не менее, это медленно! для каждого созданного нами файла верните нулевые символы в строки новой строки
sed -i 'y/\x00/\n/' csv-*
удалите промежуточный файл
rm edited
2
ответ дан 22 May 2018 в 15:46

Я хотел посмотреть, сколько из этого я мог бы сделать с sed, и мне это удалось сделать довольно много. Мы можем писать файлы с помощью sed с помощью команд w и W, но я не мог придумать способ записи другого файла с каждой итерацией цикла sed, поэтому мне пришлось использовать оболочку петля. sed, вероятно, не тот инструмент, который можно использовать для этой работы, и, вероятно, лучше сделать это с помощью sed. В любом случае, вот что я придумал:

#!/bin/bash sed ':a;N;s/\n/\x00/; ta' input | sed -r 's/\x00([0-9]+(,|\x00|$))/\n\1/g' > edited n=0 while [ -s edited ]; do ((n++)) sed -n '1p' edited > csv-"$n" sed -i '1d' edited done sed -i 'y/\x00/\n/' csv-* rm edited

Комментарии

заменяют строки новой строки нулевым символом \x00, используя петлю sed. Это значит, что позже мы можем использовать новые строки как значимые разделители. sed ':a;N;s/\n/\x00/; ta' input обрабатывает результат и добавляет новые строки перед целыми числами, которые были в первом поле, и записывает результат в файл, edited | sed -r 's/\x00([0-9]+(,|\x00|$))/\n\1/g' > edited инициализирует переменную для увеличения n=0 , пока edited не пуст, ((n++)) записать первую строку edited в новый файл csv-$n, где $n - текущее значение n sed -n '1p' edited > csv-"$n" удалить первую строку из edited sed -i '1d' edited , это конец цикла, и поскольку у нас есть только одна строка для каждого файла, который мы хотим записать, это не так медленно, как обработка каждой строки исходного файла в цикле, но тем не менее, это медленно! для каждого созданного нами файла верните нулевые символы в строки новой строки sed -i 'y/\x00/\n/' csv-* удалите промежуточный файл rm edited
2
ответ дан 17 July 2018 в 23:53

Я хотел посмотреть, сколько из этого я мог бы сделать с sed, и мне это удалось сделать довольно много. Мы можем писать файлы с помощью sed с помощью команд w и W, но я не мог придумать способ записи другого файла с каждой итерацией цикла sed, поэтому мне пришлось использовать оболочку петля. sed, вероятно, не тот инструмент, который можно использовать для этой работы, и, вероятно, лучше сделать это с помощью sed. В любом случае, вот что я придумал:

#!/bin/bash sed ':a;N;s/\n/\x00/; ta' input | sed -r 's/\x00([0-9]+(,|\x00|$))/\n\1/g' > edited n=0 while [ -s edited ]; do ((n++)) sed -n '1p' edited > csv-"$n" sed -i '1d' edited done sed -i 'y/\x00/\n/' csv-* rm edited

Комментарии

заменяют строки новой строки нулевым символом \x00, используя петлю sed. Это значит, что позже мы можем использовать новые строки как значимые разделители. sed ':a;N;s/\n/\x00/; ta' input обрабатывает результат и добавляет новые строки перед целыми числами, которые были в первом поле, и записывает результат в файл, edited | sed -r 's/\x00([0-9]+(,|\x00|$))/\n\1/g' > edited инициализирует переменную для увеличения n=0 , пока edited не пуст, ((n++)) записать первую строку edited в новый файл csv-$n, где $n - текущее значение n sed -n '1p' edited > csv-"$n" удалить первую строку из edited sed -i '1d' edited , это конец цикла, и поскольку у нас есть только одна строка для каждого файла, который мы хотим записать, это не так медленно, как обработка каждой строки исходного файла в цикле, но тем не менее, это медленно! для каждого созданного нами файла верните нулевые символы в строки новой строки sed -i 'y/\x00/\n/' csv-* удалите промежуточный файл rm edited
2
ответ дан 24 July 2018 в 17:07

Другие вопросы по тегам:

Похожие вопросы: