我相信Ctrl- C可以陷入bash脚本中。是否也可以将其捕获在Awk脚本中以处理该事件?
例如,对于中止处理,而是打印已经处理过的结果,而不是仅静默退出?
您将必须将其包装在shell脚本中或编写对awk AFAIK的扩展。
—
jai_s
我相信Ctrl- C可以陷入bash脚本中。是否也可以将其捕获在Awk脚本中以处理该事件?
例如,对于中止处理,而是打印已经处理过的结果,而不是仅静默退出?
Answers:
我不知道有任何awk
支持此功能的实现。你可以写一个扩展gawk
为,但在这里,我宁愿切换到另一种语言。
perl
使awk
使用其a2p
脚本轻松转换脚本。
例如,如果您有一个awk
脚本,例如:
{count[$0]++}
END {
for (i in count) printf "%5d %s\n", count[i], i
}
a2p
它会给你类似的东西:
#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
if $running_under_some_shell;
# this emulates #! processing on NIH machines.
# (remove #! line above if indigestible)
eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
# process any FOO=bar switches
while (<>) {
chomp; # strip record separator
$count{$_}++;
}
foreach $i (keys %count) {
printf "%5d %s\n", $count{$i}, $i;
}
您可以对其进行编辑以添加信号处理(并删除var=value
我们在此处不需要的参数处理,以及用于不支持系统的部分#!
):
#!/usr/bin/perl
sub report {
foreach $i (keys %count) {
printf "%5d %s\n", $count{$i}, $i;
}
}
$SIG{INT} = sub {
print STDERR "Interrupted\n";
report;
$SIG{INT} = 'DEFAULT';
kill('INT', $$); # report dying of SIGINT.
};
while (<>) {
chomp; # strip record separator
$count{$_}++;
}
report;
另一种替代方法可以是中断的数据馈送到awk
,并具有awk
忽略SIGINT,等代替:
awk '{count[$0]++};END{for (i in count) printf "%5d %s\n", count[i], i}' file
做:
cat file | (
trap '' INT
awk '{count[$0]++};END{for (i in count) printf "%5d %s\n", count[i], i}'
)
Ctrl+C然后将杀死cat
但不会awk
。awk
仍将继续处理仍在管道中的其余输入。
要检测Ctrl+Cin awk
,您可以执行以下操作:
(cat file && echo cat terminated normally) | (
trap '' INT
awk '{count[$0]++}
END{
if ($0 == "cat terminated normally") delete count[$0]
else print "Interrupted"
for (i in count) printf "%5d %s\n", count[i], i}'
)