Captura Ctrl-C en script awk


8

Creo que Ctrl- Cpuede ser atrapado en scripts bash. ¿También es posible atraparlo dentro de un script Awk para manejar ese evento?

Por ejemplo, para abortar el procesamiento, pero imprimir los resultados de lo que ya se ha procesado, en lugar de simplemente dejarlo en silencio.


tendrá que envolverlo en un script de shell o escribir una extensión para awk AFAIK.
jai_s


Respuestas:


10

No conozco ninguna awkimplementación que tenga soporte para eso. Podrías escribir una extensión para gawkeso , pero aquí, prefiero cambiar a otro idioma.

perlfacilita la conversión de awkscripts con su a2pscript.

Por ejemplo, si tiene un awkscript como:

{count[$0]++}
END {
  for (i in count) printf "%5d %s\n", count[i], i
}

a2p en ella te dará algo como:

#!/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;
}

Que puede editar para agregar su manejo de señal (y eliminar ese procesamiento de var=valueargumentos que no queremos aquí, y la parte destinada a sistemas que no son compatibles #!):

#!/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;

Otra alternativa podría ser la de interrumpir la alimentación de los datos a awk, y tienen awkignorar la SIGINT, al igual que en lugar de:

awk '{count[$0]++};END{for (i in count) printf "%5d %s\n", count[i], i}' file

hacer:

cat file | (
  trap '' INT
  awk '{count[$0]++};END{for (i in count) printf "%5d %s\n", count[i], i}'
)

Ctrl+Centonces matará catpero no awk. awkseguirá procesando la entrada restante en la tubería.

Para detectar la Ctrl+Cen awk, usted podría hacer:

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

¡Adopté tu ejemplo final y funciona muy bien! Gracias.
Eugene Beresovsky
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.