Как разбить файл mbox на большие куски размером n-МБ с помощью терминала?

Итак, я прочитал этот вопрос на SO но мне это не совсем помогает. Я хочу импортировать файл mbox, созданный Gmail, в другую службу веб-почты, но проблема в том, что он позволяет импортировать только 40 МБ огромных файлов.

Поэтому мне как-то нужно разбить файл mbox на макс. Файлы размером 40 МБ и импортируйте их один за другим. Как бы ты это сделал?

Моя первоначальная мысль заключалась в том, чтобы использовать другой сценарий (formail) для сохранения каждой почты в виде отдельного файла, а затем запустить сценарий, чтобы объединить их в огромные файлы размером 40 МБ, но все же я не знал, как это сделать с помощью терминала.

Я также посмотрел на команду split, но боюсь, что она отключит почту. Спасибо за любую помощь!


person Alex    schedule 23.01.2015    source источник


Ответы (4)


Если ваш mbox имеет стандартный формат, каждое сообщение будет начинаться с From и пробела:

From [email protected]

Итак, вы можете COPY YOUR MBOX TO A TEMPORARY DIRECTORY и попробовать использовать awk для его обработки по отдельности, разделяя только в начале любого сообщения. Скажем, мы использовали 1000 сообщений для каждого выходного файла:

awk 'BEGIN{chunk=0} /^From /{msgs++;if(msgs==1000){msgs=0;chunk++}}{print > "chunk_" chunk ".txt"}' mbox

тогда вы получите выходные файлы с именами от chunk_1.txt до chunk_n.txt, каждый из которых содержит до 1000 сообщений.

Если вам не повезло работать в Windows (которая не может понять одинарные кавычки), вам нужно будет сохранить следующее в файле с именем awk.txt

BEGIN{chunk=0} /^From /{msgs++;if(msgs==1000){msgs=0;chunk++}}{print > "chunk_" chunk ".txt"}

а затем введите

awk -f awk.txt mbox
person Mark Setchell    schedule 23.01.2015
comment
как удостовериться, что они около ‹40 мб каждый? - person Alex; 23.01.2015
comment
Попробуйте создать 10 000 сообщений, а если файлы слишком велики, удалите chunk файлы и увеличьте число от 10 000 до 20 000 перед повторным запуском. Это ненаучно, но я думаю, вам не нужно делать это каждый день, поэтому вам, возможно, придется немного поэкспериментировать. - person Mark Setchell; 23.01.2015
comment
я могу запустить это прямо в консоли? а mbox - это URL-адрес файла? - person Alex; 23.01.2015
comment
Если у вас нет файла mbox на вашем локальном компьютере, вам нужно сначала загрузить его. Вы можете использовать curl "http://yourprovider/somepath/mbox" > mbox.local or FTP` или щелкнуть ссылку, которую дает вам ваш провайдер. - person Mark Setchell; 23.01.2015
comment
конечно у меня есть :) мне просто интересно, что mbox в вашем скрипте - person Alex; 23.01.2015
comment
так что я сделаю из этого файл sh или что? - person Alex; 23.01.2015
comment
когда я создаю .sh файл, я получаю сообщение об ошибке: awk: syntax error at source line 2 context is /^From / >>> {msgs++;if((msgs==1000){ <<< awk: illegal statement at source line 2 awk: illegal statement at source line 2 missing ) - person Alex; 23.01.2015
comment
Я упростил его - просто скопируйте одну строку, вставьте ее в Терминал и нажмите Enter - person Mark Setchell; 23.01.2015
comment
копирование и выполнение строки в терминале дает мне следующее: awk: illegal statement at source line 1 - person Alex; 23.01.2015
comment
Он ожидает файл с именем mbox в каталоге, в котором вы выполняете команду. Введите ls -l mbox и посмотрите, видите ли вы файл mbox. - person Mark Setchell; 23.01.2015
comment
Вы не в Windows? - person Mark Setchell; 23.01.2015
comment
LOL нет им нет: D на mbp, osx 10.10 - person Alex; 23.01.2015
comment
я переименовал файл в mbox, ls -lah перечисляет его, как и ls -l mbox, но все же команда выдает синтаксическую ошибку. что-то отсутствует (или что-то в этом роде? - person Alex; 23.01.2015
comment
нет, все та же ошибка: awk: illegal statement at source line 1 я даже начал редактировать ваш ответ, чтобы убедиться, что я не копировал ненужные символы. просто кажется, что что-то не так. Понятия не имею, но для меня print > "chunk_" chunk ".txt" выглядит как-то странно, это правильный синтаксис? - person Alex; 23.01.2015
comment
Позвольте нам продолжить это обсуждение в чате. - person Mark Setchell; 23.01.2015
comment
Есть ли способ снова объединить эти файлы в один .mbox? - person Ycon; 26.06.2017
comment
@Ycon Конечно, просто переберите все фрагменты и используйте cat, чтобы добавить их вместе в новый файл mbox. - person Mark Setchell; 26.06.2017

Я только что улучшил сценарий из ответа Марка Сечелла. Как мы видим, этот скрипт может анализировать файл MBOX в зависимости от количества писем на блок. Этот улучшенный сценарий может анализировать файл mbox на основе определенного максимального размера для каждого фрагмента.
Итак, если у вас есть ограничение на размер при загрузке или импорте файла mbox, вы можете попробовать приведенный ниже сценарий, чтобы разделить файл mbox на блоки с указанным размером *.
Сохраните приведенный ниже сценарий в текстовый файл, например mboxsplit.txt в каталоге, содержащем файл mbox (например, с именем mbox):

BEGIN{chunk=0;filesize=0;}
    /^From /{
    if(filesize>=40000000){#file size per chunk in byte
        close("chunk_" chunk ".txt");
        filesize=0;
        chunk++;
    }
  }
  {filesize+=length()}
  {print > ("chunk_" chunk ".txt")}

А затем запустите / введите эту строку в этом каталоге (содержит файлы mboxsplit.txt и mbox):

  awk -f mboxsplit.txt mbox

Обратите внимание:

  • Размер результата может быть больше заданного. Это зависит от размера последнего электронного письма, вставленного в буфер / блок перед проверкой размера блока.
  • Он не разделит тело письма
  • Один блок может содержать только одно электронное письмо, если размер электронного письма больше указанного размера блока.

Я предлагаю вам указать размер блока меньше или меньше максимального размера загрузки / импорта.

person Oki Erie Rinaldi    schedule 06.03.2017
comment
Если я использую это, есть ли способ повторно объединить разделенные файлы? Спасибо - person Ycon; 26.06.2017
comment
конечно, вы можете комбинировать их! помните, что разделенные файлы - это текстовые файлы, которые можно просто объединить. - person Oki Erie Rinaldi; 04.07.2017
comment
Он отлично работал с огромными файлами mbox, созданными с помощью Google Takeout. Я использую их для импорта почты в Horde (учетные записи электронной почты GoDaddy). Я только что изменил размер файлов mbox chunk с 40 МБ на 100 МБ. - person abiyi; 18.05.2018
comment
Отличный ответ. И так быстро. - person jangeador; 12.02.2019
comment
улучшение, которое следует учитывать: используйте sprintf для обнуления индексов имен файлов. Что-то вроде: {print > ("chunk_" sprintf("%03d",chunk) ".txt");} - person Sojoodi; 21.11.2019
comment
Отличное решение, спасибо! Это пригодилось для ограничения загрузки импорта 255 МБ на roundcube. - person CodeUK; 18.05.2020

formail идеально подходит для этой задачи. Вы можете посмотреть параметры +skip и -total formail

Параметры
...
+ пропустить
Пропустить первые сообщения пропустить при разделении.
-total
Выводить не более всего сообщений при расщеплении.

В зависимости от размера вашего почтового ящика и писем вы можете попробовать

formail -100 -s <google.mbox >import-01.mbox
formail +100 -100 -s <google.mbox >import-02.mbox
formail +200 -100 -s <google.mbox >import-03.mbox

и т.п.

Разумеется, детали не обязательно должны быть одинакового размера. Если есть одно большое электронное письмо, у вас может быть только formail +100 -60 -s <google.mbox >import-02.mbox, а если много маленьких сообщений, может быть formail +100 -500 -s <google.mbox >import-02.mbox.

Чтобы найти начальное количество писем в блоке, попробуйте

formail -100 -s <google.mbox | wc
formail -500 -s <google.mbox | wc
formail -1000 -s <google.mbox | wc

Возможно, вам придется немного поэкспериментировать, чтобы приспособиться к размеру вашего почтового ящика. С другой стороны, поскольку кажется, что это одноразовая задача, возможно, вам не захочется тратить на это слишком много времени.

person Olaf Dietsche    schedule 15.04.2019

Моя первоначальная мысль заключалась в том, чтобы использовать другой сценарий (formail) для сохранения каждого письма в виде одного файла и впоследствии запустить сценарий для объединения их в огромные файлы размером 40 МБ, но все же Я бы не знал, как это сделать с помощью терминала.

Если я вас правильно понял, вы хотите разделить файлы на части, а затем объединить их в большой файл перед их импортом. Похоже на то, что должны были делать split и cat. Split разделяет файлы в зависимости от вашего размера, будь то строка или байты. Затем он добавляет к этим файлам суффикс, чтобы они были в порядке. Затем вы используете cat, чтобы собрать файлы вместе:

$ split -b40m -a5 mbox  # this makes mbox.aaaaa, mbox.aaab, etc.

Как только вы получите файлы в другой системе:

$ cat mbox.* > mbox

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

person David W.    schedule 23.01.2015
comment
не совсем, я подумал, что formail было хорошей идеей экспортировать каждое электронное письмо в отдельный текстовый файл и из них создавать куски размером около <40 МБ, чтобы я мог их импортировать. потому что разделение может разделить файл, возможно, прямо в середине электронного письма, чтобы я не мог правильно импортироваться - person Alex; 23.01.2015
comment
Split разделит письмо на два отдельных файла. Но вы произвели впечатление, что перед импортом вы рекомбинируете файлы. В таком случае не имеет значения, что split разделил отдельное электронное письмо, потому что cat собрал бы их обратно вместе. split всегда разбивается на строки. - person David W.; 23.01.2015