在awk脚本中陷阱Ctrl-C


8

我相信Ctrl- C可以陷入bash脚本中。是否也可以将其捕获在Awk脚本中以处理该事件?

例如,对于中止处理,而是打印已经处理过的结果,而不是仅静默退出?


您将必须将其包装在shell脚本中或编写对awk AFAIK的扩展。
jai_s

1
是的,请先
jlliagre

Answers:


10

我不知道有任何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但不会awkawk仍将继续处理仍在管道中的其余输入。

要检测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}'
)

我采用了您的最后一个示例,效果很好!谢谢。
尤金·别列索夫斯基'02
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.