我正在尝试对 7.6 GB 的 gzip 文件进行记录计数。我发现使用该zcat
命令的方法很少。
$ zcat T.csv.gz | wc -l
423668947
Run Code Online (Sandbox Code Playgroud)
这有效,但需要太多时间(超过 10 分钟才能获得计数)。我尝试了更多的方法,比如
$ sed -n '$=' T.csv.gz
28173811
$ perl -lne 'END { print $. }' < T.csv.gz
28173811
$ awk 'END {print NR}' T.csv.gz
28173811
Run Code Online (Sandbox Code Playgroud)
所有这三个命令的执行速度都非常快,但给出的计数不正确,为 28173811。
如何在最短的时间内执行记录计数?
Kus*_*nda 29
您提到的sed
,perl
和awk
命令可能是正确的,但它们都读取压缩数据并计算其中的换行符。这些换行符与未压缩数据中的换行符无关。
要计算未压缩数据中的行数,无法解压缩它。你用的方法zcat
是正确的做法,并且由于数据是如此之大,这将需要时间来解压。
大多数处理gzip
压缩和解压缩的实用程序很可能会使用相同的共享库例程来执行此操作。加速它的唯一方法是找到zlib
比默认例程更快的例程的实现,并重建例如zcat
使用这些例程。
mar*_*elm 21
Kusalananda的答案是正确的,你将需要解压缩是整个文件扫描其内容。/bin/gunzip
在单个内核上尽可能快地执行此操作。Pigz是gzip
可以使用多个内核的并行实现。
可悲的是,正常的gzip文件解压缩本身不能并行,但pigz
确实提供了一个改进版本gunzip
,unpigz
即做相关的工作,如阅读,写作,并在一个单独的线程执行校验。在一些快速基准测试中,unpigz
几乎是gunzip
我的核心 i5 机器的两倍。
pigz
使用您最喜欢的包管理器进行安装,并使用unpigz
代替gunzip
或unpigz -c
代替zcat
。所以你的命令变成:
$ unpigz -c T.csv.gz | wc -l
Run Code Online (Sandbox Code Playgroud)
当然,所有这些都假设瓶颈是 CPU,而不是磁盘。
所有管道的问题在于您实际上是在加倍工作。不管解压多快,数据仍然需要穿梭到另一个进程中。
Perl 有PerlIO::gzip,它允许您直接读取 gzip 压缩的流。因此,即使它的解压速度可能与以下的解压速度不匹配,它也可能提供优势unpigz
:
#!/usr/bin/env perl
use strict;
use warnings;
use autouse Carp => 'croak';
use PerlIO::gzip;
@ARGV or croak "Need filename\n";
open my $in, '<:gzip', $ARGV[0]
or croak "Failed to open '$ARGV[0]': $!";
1 while <$in>;
print "$.\n";
close $in or croak "Failed to close '$ARGV[0]': $!";
Run Code Online (Sandbox Code Playgroud)
我在具有 16 GB RAM的旧2010 MacBook Pro和具有 8 GB RAM的旧ThinkPad T400 上尝试使用 13 MB gzip 压缩文件(解压缩为 1.4 GB),该文件已在缓存中。在 Mac 上,Perl 脚本比使用管道明显快(5 秒对 22 秒),但在 ArchLinux 上,它输给了 unpigz:
$ time -p ./gzlc.pl spy.gz 1154737 真实 4.49 用户 4.47 系统 0.01
相对
$ time -p unpigz -c spy.gz | wc -l 1154737 真实 3.68 用户 4.10 系统 1.46
和
$ time -p zcat spy.gz | wc -l 1154737 真实 6.41 用户 6.08 系统 0.86
显然,unpigz -c file.gz | wc -l
就速度而言,使用在这里是赢家。而且,这个简单的命令行肯定胜过编写程序,无论程序有多短。
归档时间: |
|
查看次数: |
17935 次 |
最近记录: |