Как разделить файл журнала со значением смещения в Unix? - PullRequest
1 голос
/ 09 мая 2009

У меня действительно большой файл журнала (9 ГБ - я знаю, что мне нужно это исправить) на моей коробке. Мне нужно разбить на куски, чтобы я мог загрузить его на Amazon S3 для резервного копирования. S3 имеет максимальный размер файла 5 ГБ. Поэтому я хотел бы разделить это на несколько частей, а затем загрузить каждый из них.

Вот подвох, у меня всего 5 ГБ на моем сервере, поэтому я не могу просто сделать простой Unix-сплит. Вот что я хочу сделать:

  1. возьмите первые 4 ГБ файла журнала и выплюните в отдельный файл (назовите его сегмент 1)
  2. Загрузите этот сегмент1 в s3.
  3. rm сегмент1 для освобождения места.
  4. возьмите средние 4 ГБ из файла журнала и загрузите на s3. Очистка, как и раньше
  5. Возьмите оставшиеся 1 ГБ и загрузите на S3.

Я не могу найти правильную команду Unix для разделения со смещением. Split делает вещи одинаковыми порциями, а csplit, похоже, тоже не имеет того, что мне нужно. Любые рекомендации?

Ответы [ 4 ]

3 голосов
/ 09 мая 2009

Одно (извилистое) решение - сначала сжать его. Текстовый файл журнала должен легко перейти от 9G к значению ниже 5G, после чего вы удалите оригинал, предоставив вам 9G свободного места.

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

Загрузите их, затем удалите и распакуйте исходный журнал.

=====

Лучшее решение - просто посчитать строки (скажем, 3 миллиона) и использовать скрипт awk для извлечения и отправки отдельных частей:

awk '1,1000000 {print}' biglogfile > bit1
# send and delete bit1

awk '1000001,2000000 {print}' biglogfile > bit2
# send and delete bit2

awk '2000001,3000000 {print}' biglogfile > bit3
# send and delete bit3

Затем на другом конце вы можете либо обработать bit1 - bit3 по отдельности, либо рекомбинировать их:

mv bit1 whole
cat bit2 >>whole ; rm bit2
cat bit3 >>whole ; rm bit3

И, конечно, это разбиение может быть выполнено с помощью любого из стандартных инструментов обработки текста в Unix: perl, python, awk, head/tail combo. Это зависит от того, с чем вам удобно.

2 голосов
/ 09 мая 2009

Вы можете использовать дд. Вам нужно будет указать bs (размер буфера памяти), пропуск (количество пропускаемых буферов) и количество (количество копируемых буферов) в каждом блоке.

Таким образом, используя размер буфера 10Meg, вы должны сделать:

# For the first 4Gig
dd if=myfile.log bs=10M skip=0 count=400 of=part1.logbit
<upload part1.logbit and remove it>
# For the second 4Gig
dd if=myfile.log bs=10M skip=400 count=400 of=part2.logbit
...

Вы также можете извлечь выгоду из сжатия данных, которые вы собираетесь передавать:

dd if=myfile.log bs=10M skip=800 count=400 | gzip -c > part3.logbit.gz

Могут быть более дружелюбные методы.

ДД имеет некоторые реальные недостатки. Если вы используете небольшой размер буфера, он работает намного медленнее. Но вы можете пропустить / найти в файле только кратные значения bs. Так что, если вы хотите начать чтение данных с простого смещения, вы находитесь в реальной ситуации. Во всяком случае, я отвлекся.

2 голосов
/ 09 мая 2009

Во-первых, gzip -9 ваш файл журнала.

Затем напишите небольшой скрипт для использования dd:

#!/bin/env sh

chunk_size = 2048 * 1048576; #gigs in megabytes
input_file = shift;    

len = `stat '%s' $input_file`
chunks = $(($len/$chunk_size + 1))

for i in {0...$chunks}
do
  dd if=$input_file skip=$i of=$input_file.part count=1 bs=$chunk_size
  scp $input_file.part servername:path/$input_file.part.$i
done

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

0 голосов
/ 09 мая 2009

Разделение Coreutils создает выходные секции равного размера, за исключением последнего раздела.

split --bytes=4GM bigfile chunks
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...