如何在Awk中使用system()按指定时机单次执行Shell命令
问题根因与修复方案
异常原因
你当前遇到的重复执行问题,是因为awk的规则默认逐行匹配执行:你写的k==1 {system(...)}是全局规则,只要处理任意一行输入时k的值等于1,就会触发一次system调用,因此会执行多次。
另外你将计数器定义在system()内部的方案不生效,是因为每次system调用都会启动独立的子shell,调用结束后子shell直接销毁,变量无法在多次system调用之间共享,计数自然无效。
修复逻辑
利用awk内置变量FNR==1的特性(每个输入文件处理第一行时会命中该规则),在文件切换的间隙触发命令执行,即可保证仅执行一次:
- 当f自增到3时,代表2.txt已经处理完成,即将开始处理第三个输入文件生成3.txt,此时执行指定命令
- 当f自增到4时,代表3.txt已经处理完成,即将开始处理第四个输入文件生成4.txt,此时执行打印text2的命令
修改后完整代码
awk \ '\ FNR==1 { ++f # 2.txt生成完成,3.txt创建前执行命令 if (f == 3) { system("echo \047text\047 && sleep 4") } # 3.txt生成完成,4.txt创建前执行命令 if (f == 4) { system("echo \047text2\047 && sleep 4") } } f==1 {a[i++]=$0} f==2 {if ($0~/home_cool/) {gsub(/home_cool/, a[int(j++/2)%2]) }; print > "2.txt"} f==3 {if ($0~/home_cool/) {gsub(/home_cool/, a[int(k++/2)%3 + 2]) }; print > "3.txt"} f==4 {if ($0~/home_cool/) {gsub(/home_cool/, a[int(k++/2)%3 + 2]) }; print > "4.txt"} ' \ 1.txt 0.txt 0-1.txt 0-2.txt
代码中用\047代替单引号,是为了避免和awk脚本外层的单引号产生语法冲突,不需要额外做嵌套转义。
内容的提问来源于stack exchange,提问作者7beggars_nnnnm
相关产品推荐
相关产品推荐

