从 .gz 压缩文件中读取第一行而不解压缩整个文件

从 .gz 压缩文件中读取第一行而不解压缩整个文件

我有一个以 .gz 格式压缩的巨大日志文件,我只想读取它的第一行而不解压缩它,只检查文件中最旧日志的日期。

日志的形式如下:

YYYY-MM-DD Log content asnsenfvwen eaifnesinrng
YYYY-MM-DD Log content asnsenfvwen eaifnesinrng
YYYY-MM-DD Log content asnsenfvwen eaifnesinrng

我只想读取第一行中的日期,对于未压缩的文件我会这样做:

read logdate otherstuff < logfile.gz
echo $logdate

使用 zcat 花费的时间太长。

答案1

Pipingzcat的输出将head -n 1解压缩少量数据,保证足以显示第一行,但通常不超过几个缓冲区已满(在我的实验中为 96 KiB):

zcat logfile.gz | head -n 1

一旦head读完一行,它就会关闭其输入,从而关闭管道,并zcat在收到 a 后停止SIGPIPE(当它下次尝试写入关闭的管道时会发生这种情况)。你可以通过运行看到这一点

(zcat logfile.gz; echo $? >&2) | head -n 1

这将显示zcat退出并显示代码 141,这表明它由于SIGPIPE(13 + 128) 而停止。

您可以添加更多后处理,例如使用 AWK,仅提取日期:

zcat logfile.gz | awk '{ print $1; exit }'

(在 macOS 上,您可能需要使用gzcat而不是zcat处理 gzip 压缩文件。)

答案2

zcat您可以限制提供给( 或)的数据量gzip -dc,然后请求第一行:

head -c 1000 logfile.gz | zcat 2>/dev/null | head -1 | read logdate otherstuff

1000如果没有捕获足够的数据来获取整个第一行,请调整。

答案3

仅匹配压缩文件第一行的日期 -zgrep解决方案:

zgrep -m1 -o '^[^[:space:]]*' logfile.gz

YYYY-MM-DD这将为您输出第一个。

答案4

如果您只想要第一行而不解压文件:

gunzip -c logfile.gz | awk 'NR==1 {print; exit}'

这会将压缩数据发送到标准输出而不解压缩,并且awk仅打印第一行。

相关内容