У меня довольно большой MSG-файл, отформатированный в формате UIEE.
$ wc -l big_db.msg
8726593 big_db.msg
По сути, файл состоит из записей различной длины, которые выглядят примерно так:
UR|1
AA|Condon, Richard
TI|Prizzi's Family
CN|Collectable- Good/Good
MT|FICTION
PU|G.P. Putnam & Sons
DP|1986
ED|First Printing.
BD|Hard Cover
NT|0399132104
KE|MAFIA
KE|FICTION
PR|44.9
XA|4
XB|1
XC|BO
XD|S
UR|10
AA|Gariepy, Henry
TI|Portraits of Perseverance
CN|Good/No Jacket
MT|SOLD
PU|Victor Books
DP|1989
BD|Mass Market Paperback
NT|1989 tpb g 100 meditations from the Book of Job "This book...help you
NT| persevere through the struggles of your life..."
KE|Bible
KE|religion
KE|Job
KE|meditations
PR|28.4
XA|4
XB|5
XC|BO
XD|S
Это примеры двух записей, разделенных пустой строкой. Я хочу разбить этот большой файл на более мелкие файлы, не разбивая записи на два файла.
Каждая отдельная запись отделяется новой строкой (абсолютно пустой строкой) в файле. Я хочу разбить этот 8,7 миллионов строк файла на 15 файлов. Я понимаю, что подобные инструменты split
существуют, но я не совсем уверен, как разбить файл, но разделяю его только на новую строку, чтобы одна запись не разбивалась на несколько файлов.
text-processing
split
user2036066
источник
источник
csplit
также существует.|
(напримерUR
,AA
,TI
) значение для подсчета файлов, даже тот же быть точным?Ответы:
Вот решение, которое может работать:
Это работает, позволяя первому
sed
написать второйsed
скрипт. Второйsed
первый собирает все входные строки, пока не встретит пустую строку. Затем он записывает все выходные строки в файл. Первыйsed
выписывает скрипт для второго, инструктируя его, куда писать вывод. В моем тестовом примере этот скрипт выглядел так:Я проверил это так:
Это дало мне файл из 6000 строк, который выглядел так:
... повторяется 1000 раз.
После запуска сценария выше:
ВЫВОД
источник
Используя предложение
csplit
:Разделение на основе номеров строк
пример
Скажем, у меня есть файл с 1000 строк в нем.
результаты в файлах примерно так:
Вы можете обойти статическое ограничение необходимости указывать количество повторений, предварительно рассчитав числа на основе количества строк в вашем конкретном файле заранее.
Расщепление по пустым строкам
С другой стороны, если вы хотите просто разделить файл на пустые строки, содержащиеся в файле, вы можете использовать эту версию
split
:пример
Скажем, я добавил 4 пустые строки к
file.txt
вышеупомянутому и создаю файлfile2.txt
. Вы можете видеть, что они были добавлены вручную так:Выше показано, что я добавил их между соответствующими номерами в моем файле примера. Теперь, когда я запускаю
csplit
команду:Вы можете видеть, что у меня теперь есть 4 файла, которые были разделены на основе пустой строки:
Ссылки
источник
Если вы не заботитесь о порядке записей, вы можете сделать:
В противном случае сначала нужно получить количество записей, чтобы узнать, сколько нужно поместить в каждый выходной файл:
источник
file.in
иfile.out
?Если вы хотите разделить только в конце строки, вы сможете сделать это с
-l
опцией дляsplit
.Если вы хотите разделить пустую строку (
\n\n
), вот как я бы это сделал в ksh. Я не проверял это, и это, вероятно, не идеально, но кое-что в этом направлении будет работать:источник
\n\n
я думаю, что оп спрашивает, как разделить на части .\n\n
, а скорее не разделить в середине строки. Он называет новую строку пустой строкой.Пытаться
awk
источник
Если вам не важен порядок записей, но вы особенно заинтересованы в получении определенного количества выходных файлов, ответ Стефана - это то, что я хотел бы сделать. Но у меня есть ощущение, что вам может быть важнее указать размер, который не должен превышать каждый выходной файл. Это на самом деле делает это проще, потому что вы можете читать входной файл и собирать записи, пока не достигнете этого размера, а затем запустить новый выходной файл. Если это работает для вас, большинство языков программирования могут справиться с вашей задачей с помощью короткого сценария. Вот реализация awk:
Поместите это в файл, скажем
program.awk
, и запустите его,awk -v maxlen=10000 -f program.awk big_db.msg
где значениеmaxlen
- это наибольшее количество байтов, которое вы хотите в любом файле. Он будет использовать 500 КБ по умолчанию.Если вы хотите получить заданное количество файлов, возможно, самый простой способ - просто разделить размер вашего входного файла на количество файлов, которое вы хотите, а затем добавить немного к этому числу, чтобы получить
maxlen
. Например, чтобы получить 15 файлов из ваших 8726593 байтов, разделите на 15, чтобы получить 581773, и добавьте несколько, так что, возможно, задайтеmaxlen=590000
илиmaxlen=600000
. Если вы хотите сделать это многократно, можно было бы настроить программу для этого.источник