在保留行的同时拆分大型gz文件

时间:2017-07-12 20:22:49

标签: linux bash split terminal compression

我有一个更大的.gz文件(2.1G),我试图加载到R,但它足够大,我必须将它分成几块并在重新组合之前单独加载。但是,我很难以保留数据结构的方式拆分文件。文件本身(前两行除外)是一个56318 x 9592矩阵,具有非同质条目。

我使用的是Ubuntu 16.04。首先,我尝试使用此链接(https://askubuntu.com/questions/54579/how-to-split-larger-files-into-smaller-parts?rq=1

建议的来自终端的split命令
$ split --lines=10000 "originalFile.gct.gz" "originalFile.gct.gz.part-"
但是,这样做会创建比我预期的文件多得多的文件(因为我的矩阵有57000行,我希望输出6个文件,每个文件大小为10000行)。当将其中一个读入R并调查尺寸时,我看到每个都是62x9592的矩阵,表明列已全部保留,但我的行数明显少于我希望的行。此外,在读取它时,我收到指定文件意外结束的错误。我的想法是,它没有按照我的意愿阅读。

我在这里找到了两种可能的选择 - https://superuser.com/questions/381394/unix-split-a-huge-gz-file-by-line

特别是,我尝试使用gunzip管道不同的参数,然后将输出传递给split(假设可能正在压缩的文件导致不一致的结束行)。我试过了

$ zcat originalFile.gct.gz  | split -l 10000 "originalFile.gct.gz" "originalFile.gct.gz.part-"

但是,这样做,我最终得到了与之前完全相同的分裂。我有同样的问题替换" zcat"使用" gunzip -c",它应该将未压缩的输出发送到split命令。

该链接上的另一个答案建议使用类似zcat的东西来管道或尾部,例如

$ zcat originalFile.gct.gz | head -n 10000 >> "originalFile.gct.gz.1"

使用zcat,这非常有效,而且它正是我想要的。此尺寸最终为10000x9592,因此这是理想的解决方案。我要注意的一件事是,这个输出是一个ASCII文本文件,而不是一个压缩文件,我完全可以。

但是,我希望能够在结束文件之前执行此操作,为每10000行创建一个额外的输出文件。对于这个特殊情况,仅仅制作六个并不是一个大问题,但我有几十个这样的文件,其中一些是> 10gb。那么,我的问题是如何使用split命令来获取解压缩文件的前10000行,然后输出它们,自动更新每个新文件的后缀?基本上,我想要使用" head"得到的输出,但是" split"这样我就可以在整个文件中完成。

4 个答案:

答案 0 :(得分:2)

这是最终为我工作的解决方案

$ zcat originalFile.gct.gz | split -l 10000 - "originalFile.gtc.gz-"

正如Guido在评论中提到的,我的原始命令

$ zcat originalFile.gct.gz | split -l 10000 "originalFile.gct.gz" "originalFile.gct.gz.part-"

正在丢弃zcat的输出,并且split再次从压缩数据中读取。通过包括" - "在拆分参数之后,我能够将zcat的标准输出传递给split,现在管道就像我期望的那样工作。

答案 1 :(得分:0)

如果您想更好地控制拆分,可以使用awk。 你提到前两行很特别。 尝试像

这样的东西
zcat originalFile.gct.gz | 
   awk 'BEGIN {j=1} NR<3 {next} {i++} i%5==0 {j++} {print > "originalFile.gct.part"j }'

当您希望压缩outfiles时,请修改awk命令:让print完成的文件并使用xargs进行gzip压缩。

答案 2 :(得分:0)

如果根据文件内容进行拆分适合您。尝试:

zcat originalFile.gct.gz | awk -F$',' '{print $0 | "gzip > /tmp/name_"$1".gct.gz";}'

我文件的示例行是:2014,daniel,2,1,2,3

所以我使用

分割年份(第一列)的文件

答案 3 :(得分:0)

如果根据文件内容进行拆分适合您。尝试:

zcat originalFile.gct.gz | awk -F$',' '{print $0 | "gzip > /tmp/file_"$1".gct.gz";}'

我文件的示例行是:

2014,daniel,2,1,2,3

所以我使用变量$ 1

分割年份(第一列)的文件

获取和输出:

/tmp/file_2014.gct.gz
/tmp/file_2015.gct.gz
/tmp/file_2016.gct.gz
/tmp/file_2017.gct.gz
/tmp/file_2018.gct.gz