私は信じている Ctrl-C bashスクリプトにトラップされる可能性があります。そのイベントを処理するためにAwkスクリプト内にトラップすることも可能ですか?
たとえば、処理を中止するが、単に黙って終了するのではなく、すでに処理されたものの結果を出力する場合はどうでしょうか。
私はそれをサポートしている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;
もう1つの方法は、データのフィードを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+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}'
)