只处理Tcl中gzip压缩文件的前n行

时间:2017-08-06 19:15:35

标签: tcl

我需要从前n行(大约50行)中提取文本文件中的一些字符串值。在某些情况下,文件是gzip压缩的,在某些情况下它们不是。

目前,我使用以下内容来读取文件,但这会读取整个文件并且处理非常大的文件的速度很慢。

set f [open "| zcat -f $filename" r]

如果文件没有被gzip压缩,那么这似乎工作正常并且看起来非常快。

set f [open "| head -n 50 $filename" r]

但是当它被gzip压缩时,我似乎只能在前n行中找到zcat。我试过这个,但是在tclsh

我收到了错误
set f [open "| zcat -f $filename | head -n 50" r]
set data [read $f]
close $f

%child killed: write on pipe with no readers

我可以尝试捕捉错误并继续前进,因为它似乎将数据推送到$ data变量中,但我想知道我是否在这里做了非法的事情。

或者,是否有纯Tcl方法来实现这一目标?

1 个答案:

答案 0 :(得分:1)

错误来自close,因为zcat在写完所有行之前已停止(通过信号SIGPIPE)。这是预期的,你可以安全地catch并忽略它。将catch放在close附近。

在Tcl 8.6中(但不是任何以前的版本,也不是Tcl的独立zlib包;这是我们在将包导入Tcl时添加的功能),您可以在纯Tcl中执行此操作。

set f [open $filename]
zlib push gunzip $f

# Read those lines! This oneliner is a hack!
set lines [lmap - [lrepeat 50 -] {gets $f}]

# NB: We don't need to put a catch around this now
close $f

zlib命令提供压缩和解压缩; zlib push用于向频道添加压缩或解压缩,例如在已应用gunzip频道过滤器的情况下。