如何加速调用多个awk脚本的Windows批处理文件?
优化AWK脚本与Windows批处理的运行速度
我编写了一个调用自定义AWK脚本(append和footnote)的Windows批处理文件,原代码如下:
@ECHO off type compiler-books.txt | awk -f append -v filename="economics-books.txt" | awk -f footnote
之后我给批处理加上计时命令,统计脚本运行时长:
@ECHO off set start_date=%date% %time% type compiler-books.txt | awk -f append -v filename="economics-books.txt" | awk -f footnote set end_date=%date% %time% powershell -command "&{$start_date1 = [datetime]::parse('%start_date%'); $end_date1 = [datetime]::parse('%date% %time%'); echo (-join('Duration in seconds: ', ($end_date1 - $start_date1).TotalSeconds)); }"
结果显示处理两个极小的输入文件居然耗时约0.5秒,速度不理想,想知道有哪些提速方案。
现有AWK脚本与输入文件内容
append AWK脚本:
BEGIN {FS="\t"; OFS="\t"} { print } END { while ((getline < filename) > 0) print }
footnote AWK脚本:
BEGIN {FS="\t"; OFS="\t"} NR==1 { print; author_list=$2 } NR>1 { print; author_list=author_list ", " $2 } END { print author_list}
制表符分隔的compiler-books.txt:
Compilers Principles, Techniques, Tools Alfred V. Aho, Ravi Sethi, Jeffrey Ullman Addison-Wesley 1986 Introduction to Compiling Techniques J. P. Bennett McGraw-Hill 1996
制表符分隔的economics-books.txt:
Economic Facts and Fallacies Thomas Sowell Basic Books 2011 Economics in One Lesson Henry Hazlitt Harper & Brothers 1946
提速方案
合并AWK脚本,减少进程启动开销:
当前批处理启动了type、两次awk共3个进程,还用到两个管道,这些进程启动和管道交互的开销远大于实际文件处理的时间。把两个脚本合并成一个,只启动一次awk就能完成所有操作。合并后的脚本
combined.awk:BEGIN {FS="\t"; OFS="\t"} # 处理第一个文件(compiler-books.txt) FILENAME == ARGV[1] { print process_author($2) next } # 处理第二个文件(economics-books.txt) FILENAME == ARGV[2] { print process_author($2) next } # 作者列表处理函数 function process_author(author) { if (author_list == "") { author_list = author } else { author_list = author_list ", " author } } END { print author_list }直接用AWK读取文件,去掉
type命令:
AWK本身支持直接读取多个文件,不需要通过type管道传递内容,进一步减少进程开销。优化后的批处理文件:
@ECHO off set start_date=%date% %time% awk -f combined.awk compiler-books.txt economics-books.txt set end_date=%date% %time% powershell -command "&{$start_date1 = [datetime]::parse('%start_date%'); $end_date1 = [datetime]::parse('%date% %time%'); echo (-join('Duration in seconds: ', ($end_date1 - $start_date1).TotalSeconds)); }"简化逻辑,避免
getline的额外开销:
原append脚本用getline读取第二个文件,不如直接让AWK把第二个文件作为命令行参数处理,逻辑更清晰且效率更高。
内容的提问来源于stack exchange,提问作者Roger Costello
相关产品推荐
相关产品推荐

