考虑这个文件:
#!/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