如何在AWK脚本内将全部输出同时打印到终端并写入文件?
AWK 同时输出到终端和文件的实现方案
完全不需要给每一条print重复写重定向代码,按你的场景选对应方案即可:
方案1:零业务代码修改(全版本兼容,最稳定)
如果你不需要把双写逻辑完全硬编码在awk脚本内部,这是成本最低的方案:脚本里所有print/printf原封不动,调用脚本时把输出管道给系统自带的tee命令就行:
# 每次运行覆盖旧日志 awk -f your_script.awk 输入文件 | tee thisiswhack.out # 追加写日志加-a参数 awk -f your_script.awk 输入文件 | tee -a thisiswhack.out
tee会自动把所有标准输出内容同步打印到终端、写入指定文件,兼容所有版本的awk实现,没有额外兼容问题。
方案2:逻辑全封装在脚本内部
适用于GNU Awk(绝大多数Linux环境默认的awk版本)
只需要在BEGIN块加几行初始化代码,后面所有业务逻辑里的print/printf完全不用改,自动实现双写:
#!/usr/bin/awk -f BEGIN { log_file = "thisiswhack.out" # 要追加写日志就删掉下面这行清空旧日志的代码 printf "" > log_file # 启动tee协程,绑定标准输出到协程 tee_proc = "tee -a " log_file close(1) print "" |& tee_proc } # 下面是你原来的代码,完全不用动 { # 数据处理逻辑 print "This is an awk script" # 原来的print语句不管带多少参数,原写法保留即可 } END { print "Yay we're done!" # 脚本退出前关闭协程,确保所有内容写入文件 close(tee_proc, "to") }
适用于macOS/BSD自带awk等不支持协程的环境
如果环境里的awk不支持协程特性,可以自定义统一的输出函数,只需要做一次全局替换:把脚本里所有print 替换成log_print 即可,后续要改日志路径、调整输出格式只需要改函数,不用动业务代码,比每句重复写重定向维护成本低很多:
#!/usr/bin/awk -f BEGIN { log_file = "thisiswhack.out" # 追加写就删掉下面清空日志的行 printf "" > log_file } function log_print(out, i) { for (i = 2; i < length(PROCINFO["argv"]); i++) { out = out OFS argv[i] } print out print out >> log_file }
注意:如果你的print语句带多个参数,把参数按顺序传给log_print即可,拼接规则和原生print完全一致。
内容的提问来源于stack exchange,提问作者A. Salas
相关产品推荐
相关产品推荐

