awk:将(条件)打印的输出管道传输到 gzip

awk:将(条件)打印的输出管道传输到 gzip

考虑这个文件:

#!/usr/bin/env bash
cat > example_file.txt <<EOL
group, value
1, 3.21
1, 3.42
1, 3.5
2, 4.1
2, 4.2
EOL

在以下脚本中,我根据第一列中的值对此文件的行进行分组(第一列中的值已经排序)并将每个组打印到单独的 txt 文件中:

var=$(echo 'example_file.txt')
var2=$(echo $var|sed "s/.txt//g")
mkdir -p output
cat $var | awk -v varn="$var2" -F, 'FNR == 1 {header = $0;next} !seen[$1]++ { print header > ("output/"varn"_"$1".txt") }{print > ("output/"varn"_"$1".txt");}'

问题

如何将结果打印到压缩流"output/"varn"_"$1".gz"(而不是未压缩的 txt 文件"output/"varn"_"$1".txt")?

(因此所需的输出与脚本现在生成的输出相同,只是我希望输出的文件被压缩并保存为文件,.txt.gz而不是像代码现在那样保存为纯文本文件)。

(我尝试在块gzip >内使用{print}但无济于事:(

(PS:我有点不懂什么,所以这个问题可能真的很愚蠢。)

答案1

您可以通过管道连接到 GNU awk 中的命令print。从GNU awk 手册

print items | command

可以通过管道将输出发送到另一个程序,而不是发送到文件中。此重定向打开一个到命令的管道,并通过此管道将项目的值写入为执行命令而创建的另一个进程。

重定向参数command实际上是一个 awk 表达式。它的值被转换为一个字符串,其内容给出要运行的 shell 命令。例如,以下生成两个文件,一个是未排序的人名列表,另一个是按字母顺序反向排序的列表:

awk '{ print $1 > "names.unsorted"
       command = "sort -r > names.sorted"
       print $1 | command }' mail-list

所以:

awk -v varn="$var2" -F, 'FNR == 1 {header = $0;next}
  !seen[$1]++ { print header | "gzip > "output/"varn"_"$1".gz" }
  {print | "gzip > output/"varn"_"$1".gz";}'

例如:

% echo 1 2 | awk '{print $2 | "gzip > "$1".gz"}'
% zcat 1.gz 
2

相关内容