在 awk 脚本中读取多个压缩文件

在 awk 脚本中读取多个压缩文件

我有一个名为 的 awk 脚本text_processing.awk。我需要将多个名为 等的压缩文件传递01JAN21.txt.gz02JAN21.txt.gz此脚本以进行进一步处理。输出文件从输入文件中获取日期并命名result_01JAN21.txt等等。

请注意,这些文件是压缩的。

我首先尝试使用下面的命令在一个文件上运行

zcat 01JAN21.txt.gz | awk -f text_processing.awk -

但是,我的输出文件没有被命名,我相信因为这个命令只是打开文件并将其通过管道传输到脚本,而我的脚本从输入文件名中提取日期,如下所示

BEGIN{ 
  FS = ";" 
  input_file = ARGV[1] 
  sub(/\.txt\.gz/, "", input_file) 
  output = "result_" input_file ".txt 
}

将不胜感激有关如何纠正它的一些指导。我想在 awk 脚本中保留输出文件的重命名,因为我将一次性传递多个文件。

答案1

假设您要处理当前目录中名称匹配的所有文件*.txt.gz。将名称作为变量传递到awk并流式传输未压缩的数据:

for name in *.txt.gz; do
    gzip -c -d -- "$name" |
    awk -v name="$name" -f text_processing.awk
done

awk代码中,您将使用name变量来计算输出文件名。

或者,让 shell 脚本为您提供要使用的显式输出文件名:

for name in *.txt.gz; do
    gzip -c -d -- "$name" |
    awk -v outname="result_${name%.gz}" -f text_processing.awk
done

该字符串将是删除并添加前缀的result_${name%.gz}原始文件的名称。然后代码用于写入。.gzresult_awkoutname

显然,如果您的awk代码仅写入单个输出文件,您可以awk进一步简化代码并将其打印到其标准输出。然后在 shell 中进行输出重定向:

for name in *.txt.gz; do
    gzip -c -d -- "$name" |
    awk -f text_processing.awk >"result_${name%.gz}"
done

评论中要求的额外材料:awk并行运行命令。

为此,我将使用xargs,并且假设该实用程序支持非标准选项-0(用于读取以 nul 结尾的数据)、-r(用于在没有输入时不执行给定的命令)和-P(用于运行并行工作)。

print '%s\0' *.txt.gz |
xargs -0r -P 4 -I {} sh -c '
    gzip -c -d -- "$1" |
    awk -f text_processing.awk >"result_${1%.gz}"' sh {}

这将同时运行四个文件的gzip+管道。awk添加-txargs实用程序的选项以获取和指示它正在生成哪些命令。

相关内容