问题描述
根据此问题的先前答案,我有以下awk脚本的示例https://stackoverflow.com/a/69874658/10824251:
awk
'
FNR==1 {++f}
f==1 {a[i++]=$0}
f==2 {if ($0~/home_cool/) {gsub(/home_cool/, a[int(j++/2)%2]) }; print > "2.txt"}
k==1 {system("echo 'text' && sleep 4")}
f==3 {if ($0~/home_cool/) {gsub(/home_cool/, a[int(k++/2)%3 + 2]) }; print > "3.txt"}
k==1 {system("echo 'text2' && sleep 4")}
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
我尝试仅在创建2.txt
文件之后和创建3.txt
文件之前添加一次运行的命令外壳程序。
这意味着只有在完全创建2.txt
文件后才能执行特定的外壳命令。
解决方案还应能够在4.txt
要创建之前打印text2
。
我正在使用system()
,到目前为止,我的尝试不能很好地工作,唯一不能工作的是外壳脚本执行了3次,而不是1次(从屏幕上的3个text
打印可以看出这一点)。
在创建2.txt
之前,echo 'text'
只运行了一次,我可以做些什么来查看真正遗漏了什么才能解决此问题?
我尝试在system()
(system("counter=0; if [[ "$counter" -gt 2 ]] then echo "text" fi; sleep 4")
)中插入一个计数器(没有whil
e),但没有作用,而且这真的没有多大意义,因为我认为counter=0
应该在system()
之外。
澄清已解决状态的答案选择注意事项:
怀疑复杂和残酷,选择我将给出的答案作为答案:
一方面,用户@Dan Answer(作者对awk
上一期档号的回答)自己解释的简单性;
另一方面,答案对向user@markp-fuso学习非常有用的深化。
也许当其他用户需要阅读这个问题时,我应该考虑他们,所以我将选择如何解决markp-fuso问题。我希望了解这个问题的所有答案的作者。
推荐答案
主要问题(在标准输出上重复text/text2
条目)似乎来自对awk
变量k
的双重使用和某些缺少的输入控件。
awk
变量k
正被第二次和第三次gsub(... k++ ...)
调用用作自动递增索引;k
绝不会重置为0
(或1
),因此从逻辑上讲,操作k==1
测试应该只发生一次。但是...将对k==1
的每一个输入行(来自所有文件)进行测试...对于带有和不带有home_cool
字符串的行都会发生这种情况;并且因为有两个k==1
测试正在为每一个输入行进行验证,所以只要k==1
,OP将获得双重输出(text
和text2
)。还请记住,对于字符串为home_cool
的行,k
只会递增(通过gsub()
调用);没有home_cool
的行将看到不变的k==1
,因此两个k==1
测试也将为这些行触发;我们将在标准输出上获得额外的text/text2
条目,直到下一次gsub()
触发并递增k
(通过k++
)我建议使用不同的变量(例如,p
)来确定何时打印text/text2
条目,并将k==1
测试(现在为if (p)
)移动到仅在适当的时候运行的位置。
重写的一个想法:
awk '
FNR==1 {++f; p=1} # reset our "p"rintme? flag for each new file
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])}
if (p) # old "k==1" test; if "p"rintme flag set then ...
{print "text"; system("sleep 4"); p=0} # print, sleep, clear flag
print > "3.txt"
}
f==4 {if ($0~/home_cool/)
{gsub(/home_cool/, a[int(k++/2)%3 + 2])}
if (p) # old "k==1" test; if "p"rintme flag set then ...
{print "text2"; system("sleep 4"); p=0} # print, sleep, clear flag
print > "4.txt"
}
' 1.txt 0.txt 0-1.txt 0-2.txt
运行时,这将在标准输出上生成以下内容:
text
text2
备注:
- 除了打印问题,我假设op的逻辑是正确的(即
[234].txt
文件的内容是正确的) - 如果输入文件为空,则关联的
f==?
测试将不会触发,这意味着... - 关联的
if (p)...
测试/操作将不会触发; - 例如...
- 如果
0-2.txt
为空,则f==4
永远不会检测为阳性,因此... - 关联的
if (p) ... print "text2" ...
将不会触发 - 我不清楚,如果相应的文件为空,OP是否需要有条件地打印
text/text2
消息... - 修改代码很容易,但我现在跳过这一步,以减少混淆
这篇关于使用system()在Awk中只运行一次外壳命令,即只打印一次文本(&q;)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!