我有一个名为 的 awk 脚本text_processing.awk
。我需要将多个名为 等的压缩文件传递01JAN21.txt.gz
给02JAN21.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}
原始文件的名称。然后代码用于写入。.gz
result_
awk
outname
显然,如果您的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
添加-t
到xargs
实用程序的选项以获取和指示它正在生成哪些命令。