将STDIN拆分为多个文件(如果可能的话压缩它们)



我有一个程序(gawk),它将数据流输出到它的STDOUT。处理的数据实际上是10gb。我不想把它保存在一个文件中,而是把它分成几个块,并在保存之前对每个块应用一些额外的处理(如压缩)。

我的数据是一个记录序列,我不想把记录分成两半。每个记录匹配以下regexp:

^{index.+?}}n{.+?}$

或者为了简单起见,可以假设两行(首先是不均匀的,然后即使从流的开始编号)总是构成一条记录。

我可以:

  • 使用一些标准的linux命令来划分STDIN通过定义块的优选大小?不需要精确,因为记录变量大小不能保证。或者,如果不可能按大小定义,则仅记录数量
  • 压缩每个块并存储在一个文件中(在其名称中有一些编号,如001,002等)

我已经知道像GNU parallel或csplit这样的命令,但不知道如何将它们组合在一起。如果上面解释的功能可以在不编写自定义perl脚本的情况下实现,那就太好了。然而,这可能是另一个,最后的解决方案,但我不确定如何最好地实现它。

GNU Parallel可以将stdin拆分为记录块。这将把stdin分割成50 MB的块,每个记录为2行。每个块将被传递给gzip并压缩到名称[chunk number].gz:

cat big | parallel -l2 --pipe --block 50m gzip ">"{#}.gz

如果你知道你的第二行永远不会以'{index'开头,你可以使用'{index'作为记录的开头:

cat big | parallel --recstart '{index' --pipe --block 50m gzip ">"{#}.gz

你可以很容易地测试分割是否正确:

parallel zcat {} | wc -l ::: *.gz

除非你的记录都是相同的长度,否则你可能会看到不同的行数,但都是偶数。

观看一个简短的介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

遍历教程(man parallel_tutorial)。命令行我会爱你的。

您可以使用split实用程序(与parallel相比,GNU coreutils包附带的,因此更多机会在目标系统上找到),它可以读取STDIN(除了普通文件),使用按行或按大小阈值,并通过--filter CMD选项将自定义逻辑应用于块。请参考相应的手册页了解详细的使用方法。

cat target | split -d -l10000 --suffix-length 5 --filter 'gzip > $FILE.gz' - prefix.

将STDIN拆分为gzip块,每个块10000行,名称为prefix.<CHUNK_NUMBER>,其中<CHUNK_NUMBER>从0开始,并用0填充到5的长度(例如00000, 00001, 00002等)。起始号码和额外后缀也可以设置

相关内容

  • 没有找到相关文章

最新更新