我有 file.gz (不是 .tar.gz !)或 file.zip 文件。它包含一个名为1.txt
的文件(带有数千万行的20GB大小的文本文件)。
1.txt
整体保存到磁盘(此要求与my previous question中的相同),我想提取与正则表达式匹配的所有行,并且不匹配另一个正则表达式。 .txt
文件不得超过预定义的限制,例如一百万行。 也就是说,如果1.txt
中有3.5M行匹配这些条件,我想得到4个输出文件:part1.txt,part2.txt,part3.txt,part4.txt(后者将包含500K行),就是这样。
我试图使用像
这样的东西gzip -c path/to/test/file.gz | grep -P --regexp='my regex' | split -l1000000
但上面的代码不起作用。也许Bash可以做到,就像在previous question中一样,但我不知道如何。
答案 0 :(得分:3)
您可以使用zgrep
。
zgrep [ grep_options ] [ -e ] pattern filename.gz ...
注意:zgrep
是一个包装脚本(与gzip
软件包一起安装),它基本上在内部使用与其他答案中提到的相同的命令。
但是,它在脚本中看起来更具可读性。更容易手动编写命令。
答案 1 :(得分:2)
我害怕它是不可能的,引自gzip
男人:
如果您希望创建包含多个成员的单个存档文件 以后可以单独提取成员,使用归档程序 如焦油或拉链。
更新:在编辑之后,如果gz
只包含一个文件,那么像awk
这样的一步工具就可以了:
gzip -cd path/to/test/file.gz | awk 'BEGIN{global=1}/my regex/{count+=1;print $0 >"part"global".txt";if (count==1000000){count=0;global+=1}}'
split
也是一个不错的选择,但您必须在其后重命名文件。
答案 2 :(得分:1)
你的解决方案几乎是好的。问题是你应该为gzip
指定做什么。要解压缩使用-d。所以试试:
gzip -dc path/to/test/file.gz | grep -P --regexp='my regex' | split -l1000000
但是有了这个你会有一堆像xaa,xab,xac这样的文件......我建议使用PREFIX和数字后缀功能来创建更好的输出:
gzip -dc path/to/test/file.gz | grep -P --regexp='my regex' | split -dl1000000 - file
在这种情况下,结果文件将如下所示:file01,file02,fil03等。
如果你想过滤掉一些不匹配的perl样式正则表达式,你可以尝试这样的事情:
gzip -dc path/to/test/file.gz | grep -P 'my regex' | grep -vP 'other regex' | split -dl1000000 - file
我希望这会有所帮助。