运行 Shell Awk 内部命令仅一次 'per command' 使用 System(),即仅打印一次 "text"
Run Shell Command Inside Awk only Once 'per command' Using System(), i e, print only Once "text"
根据此处对该问题的先前回答,我有下面的 awk 脚本示例 :
awk \
'
FNR==1 {++f}
f==1 {a[i++]=[=14=]}
f==2 {if ([=14=]~/home_cool/) {gsub(/home_cool/, a[int(j++/2)%2]) }; print > "2.txt"}
k==1 {system("echo 'text' && sleep 4")}
f==3 {if ([=14=]~/home_cool/) {gsub(/home_cool/, a[int(k++/2)%3 + 2]) }; print > "3.txt"}
k==1 {system("echo 'text2' && sleep 4")}
f==4 {if ([=14=]~/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
文件之前仅添加一次命令 shell 运行。
这意味着特定的shell命令只能在2.txt
文件完全创建后执行。
解决方案还应该能够在 4.txt
之前打印 text2
来创建 .
我正在使用 system()
,到目前为止我的尝试效果不佳,唯一不起作用的是 shell 脚本执行了 3 次而不是 1 次(这可以可以看到屏幕上的 3 text
个打印件。
我该怎么做才能看到真正遗漏了什么来解决这个问题 echo 'text'
是 运行 只有一次并且在 2.txt
被创建之前?
我试图在 system()
(system("counter=0; if [[ "$counter" -gt 2 ]] then echo "text" fi; sleep 4")
) 中插入一个计数器(没有 whil
e)但是没有用,而且它真的没有多大意义,因为 counter=0
应该是 system()
我相信。
说明已解决状态的答案选择:
疑惑复杂而残酷,选择我将给出的答案作为解决:
一方面是用户@dan 的回答(作者在awk
上一期的回答中的回答);
另一方面,从用户@markp-fuso 那里得到了一个非常有用的深化学习答案。
也许其他用户需要阅读这个issue的时候我应该想想,所以我会选择如何解决markp-fuso的issue。希望能理解所有回答这个问题的作者
What can I do to see what really misses to solve this and echo 'text'
is run only once and before 2.txt
be created?
如果您想要以下行为:仅 运行 如果 2.txt
不存在则更改
{system("echo 'text' && sleep 4")}
至
{system("ls 2.txt && echo 'text' && sleep 4")}
如果没有 2.txt
ls
将发生故障并阻止执行超出 &&
的内容。请注意,ls
确实会发出输出,如果这在您的情况下不可接受,您将需要为 ls
添加 stdout
和 stderr
重定向到 /dev/null
。
I am trying to add a command shell only one time run after creating the 2.txt file and before creating the 3.txt file.
为 FNR==1
添加测试,作为 f==3
块的第一个命令,如下所示:
f==3 {if (FNR==1) {system("##")}; if ([=10=]~/home_cool/) {gsub(/home_cool/, a[int(k++/2)%3 + 2]) }; print > "3.txt"}
它将在该块中的任何其他内容之前执行。
或者,您可以直接在 f==3
上方添加此 pattern {action}
:
f==3 && FNR==1 {system("##")}
f==3 {if ([=11=]~/home_cool/) {gsub(/home_cool/, a[int(k++/2)%3 + 2]) }; print > "3.txt"}
pattern/action 块总是按照给定的顺序执行,所以同样,它会先执行。
您认为哪个更具可读性。
主要问题(在 stdout 上重复 text/text2
个条目)似乎是 awk
变量 k
的双重使用和一些缺失的输入控制。
第 2 和第 3 次 gsub(... k++ ...)
调用将 awk
变量 k
用作自动递增索引; k
绝不会重置为 0
(或 1
),因此从逻辑上讲,OPs k==1
测试应该只发生一次。然而...
k==1
的测试将针对每个输入行(来自所有文件)发生...这发生在有和没有 home_cool
字符串的行;并且因为有两个 k==1
测试正在为每个输入行验证 OP 将获得双输出(text
和 text2
)只要 k==1
.
另外请记住,k
仅针对字符串 home_cool
的行递增(通过 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++]=[=10=]}
f==2 {if ([=10=]~/home_cool/)
{gsub(/home_cool/, a[int(j++/2)%2]) }
print > "2.txt"
}
f==3 {if ([=10=]~/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 ([=10=]~/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)...
test/operation 不会触发;
- 例如...
- 如果
0-2.txt
为空,则 f==4
永远不会测试为阳性,所以 ...
- 关联的
if (p) ... print "text2" ...
不会触发
- 不清楚(对我来说)如果相应的文件为空,OP 是否需要有条件地打印
text/text2
消息...
- 修改代码很容易,但我现在将跳过它以减少混淆
根据此处对该问题的先前回答,我有下面的 awk 脚本示例
awk \
'
FNR==1 {++f}
f==1 {a[i++]=[=14=]}
f==2 {if ([=14=]~/home_cool/) {gsub(/home_cool/, a[int(j++/2)%2]) }; print > "2.txt"}
k==1 {system("echo 'text' && sleep 4")}
f==3 {if ([=14=]~/home_cool/) {gsub(/home_cool/, a[int(k++/2)%3 + 2]) }; print > "3.txt"}
k==1 {system("echo 'text2' && sleep 4")}
f==4 {if ([=14=]~/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
文件之前仅添加一次命令 shell 运行。
这意味着特定的shell命令只能在2.txt
文件完全创建后执行。
解决方案还应该能够在 4.txt
之前打印 text2
来创建 .
我正在使用 system()
,到目前为止我的尝试效果不佳,唯一不起作用的是 shell 脚本执行了 3 次而不是 1 次(这可以可以看到屏幕上的 3 text
个打印件。
我该怎么做才能看到真正遗漏了什么来解决这个问题 echo 'text'
是 运行 只有一次并且在 2.txt
被创建之前?
我试图在 system()
(system("counter=0; if [[ "$counter" -gt 2 ]] then echo "text" fi; sleep 4")
) 中插入一个计数器(没有 whil
e)但是没有用,而且它真的没有多大意义,因为 counter=0
应该是 system()
我相信。
说明已解决状态的答案选择:
疑惑复杂而残酷,选择我将给出的答案作为解决:
一方面是用户@dan 的回答(作者在awk
上一期的回答中的回答);
另一方面,从用户@markp-fuso 那里得到了一个非常有用的深化学习答案。
也许其他用户需要阅读这个issue的时候我应该想想,所以我会选择如何解决markp-fuso的issue。希望能理解所有回答这个问题的作者
What can I do to see what really misses to solve this and echo 'text' is run only once and before
2.txt
be created?
如果您想要以下行为:仅 运行 如果 2.txt
不存在则更改
{system("echo 'text' && sleep 4")}
至
{system("ls 2.txt && echo 'text' && sleep 4")}
如果没有 2.txt
ls
将发生故障并阻止执行超出 &&
的内容。请注意,ls
确实会发出输出,如果这在您的情况下不可接受,您将需要为 ls
添加 stdout
和 stderr
重定向到 /dev/null
。
I am trying to add a command shell only one time run after creating the 2.txt file and before creating the 3.txt file.
为 FNR==1
添加测试,作为 f==3
块的第一个命令,如下所示:
f==3 {if (FNR==1) {system("##")}; if ([=10=]~/home_cool/) {gsub(/home_cool/, a[int(k++/2)%3 + 2]) }; print > "3.txt"}
它将在该块中的任何其他内容之前执行。
或者,您可以直接在 f==3
上方添加此 pattern {action}
:
f==3 && FNR==1 {system("##")}
f==3 {if ([=11=]~/home_cool/) {gsub(/home_cool/, a[int(k++/2)%3 + 2]) }; print > "3.txt"}
pattern/action 块总是按照给定的顺序执行,所以同样,它会先执行。
您认为哪个更具可读性。
主要问题(在 stdout 上重复 text/text2
个条目)似乎是 awk
变量 k
的双重使用和一些缺失的输入控制。
第 2 和第 3 次 gsub(... k++ ...)
调用将 awk
变量 k
用作自动递增索引; k
绝不会重置为 0
(或 1
),因此从逻辑上讲,OPs k==1
测试应该只发生一次。然而...
k==1
的测试将针对每个输入行(来自所有文件)发生...这发生在有和没有 home_cool
字符串的行;并且因为有两个 k==1
测试正在为每个输入行验证 OP 将获得双输出(text
和 text2
)只要 k==1
.
另外请记住,k
仅针对字符串 home_cool
的行递增(通过 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++]=[=10=]}
f==2 {if ([=10=]~/home_cool/)
{gsub(/home_cool/, a[int(j++/2)%2]) }
print > "2.txt"
}
f==3 {if ([=10=]~/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 ([=10=]~/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)...
test/operation 不会触发; - 例如...
- 如果
0-2.txt
为空,则f==4
永远不会测试为阳性,所以 ... - 关联的
if (p) ... print "text2" ...
不会触发 - 不清楚(对我来说)如果相应的文件为空,OP 是否需要有条件地打印
text/text2
消息... - 修改代码很容易,但我现在将跳过它以减少混淆