awkスクリプトでCtrl-Cをトラップする


8

私は信じているCtrl- Cのbashスクリプトでトラップすることができます。そのイベントを処理するために、Awkスクリプト内にトラップすることもできますか?

たとえば、処理を中止するが、静かに終了するのではなく、すでに処理された結果を出力する場合はどうでしょうか。


シェルスクリプトでラップするか、awk AFAIKの拡張機能を記述する必要があります。
jai_s

1
はい、読むことから始めている:gnu.org/software/gawk/manual/html_node/...
jlliagre

回答:


10

awkそれをサポートしている実装については知りません。そのための拡張を書くgawkこともできますが、ここでは別の言語に切り替えたいと思います。

perlawkスクリプトを使用してスクリプトを簡単に変換でき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、としているawkSIGINTを無視し、代わりのように:

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+Cawk、次のようにします。

(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}'
)

あなたの最後の例を採用しました。ありがとう。
Eugene Beresovsky、2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.