如何在unix中拆分带偏移值的日志文件?

时间:2009-05-09 01:55:04

标签: unix split

我的盒子上有一个非常大的日志文件(9GB - 我知道我需要修复它)。我需要拆分成块,这样我就可以将它上传到亚马逊S3进行备份。 S3的最大文件大小为5GB。所以我想把它分成几个块,然后上传每个块。

这是捕获,我的服务器上只有5GB空闲,所以我不能只做一个简单的unix拆分。这就是我想要做的事情:

  1. 抓住第一个4GB的日志文件并吐出一个单独的文件(称之为段1)
  2. 将该段1上传到s3。
  3. rm segment1释放空间。
  4. 从日志文件中获取中间4GB并上传到s3。像以前一样清理
  5. 抓住剩余的1GB并上传到S3。
  6. 我找不到正确的unix命令来分割偏移量。拆分只能做相同的块,csplit似乎没有我需要的东西。有什么建议吗?

4 个答案:

答案 0 :(得分:3)

一个(复杂的)解决方案是先压缩它。文本日志文件应该很容易从9G到5G以下,然后删除原始文件,为您提供9G的可用空间。

然后直接通过split管道压缩文件,以免耗尽更多磁盘空间。你最终得到的是一个压缩文件和三个上传文件。

上传它们,然后删除它们,然后解压缩原始日志。

=====

更好的解决方案是计算行数(比如300万)并使用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

然后,在另一端,您可以单独处理bit1bit3,也可以重新组合它们:

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

当然,这种拆分可以使用Unix中的任何标准文本处理工具完成:perlpythonawkhead/tail组合。这取决于你感到满意。

答案 1 :(得分:2)

首先,gzip -9你的日志文件。

然后,编写一个小的shell脚本来使用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

我只是把它从脑袋里掏出来,所以我不知道它是否会在没有修改的情况下发挥作用,但是你需要的东西非常相似。

答案 2 :(得分:2)

你可以使用dd。您需要在每个块中指定bs(内存缓冲区大小),skip(要跳过的缓冲区数)和count(要复制的缓冲区数)。

因此,使用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

可能有更友好的方法。

dd有一些真正的缺点。如果使用较小的缓冲区大小,则运行速度要慢得多。但是你只能通过bs的倍数跳过/搜索文件。因此,如果您想要从素数偏移量开始读取数据,那么您就是一个真正的小提琴手。无论如何我离题了。

答案 3 :(得分:0)

Coreutils split会创建相同大小的输出节,但最后一节除外。

split --bytes=4GM bigfile chunks