Intereting Posts
Как Windows DHCP-сервер может обновлять DNS-сервер в Linux? Поиск точек монтирования с помощью команды find? Как получить доступ к корневой файловой системе для запуска cryptsetup, чтобы разрешить доступ к корневой файловой системе? ESET NOD32 esets_daemon syslog flood Что вызывает прерывание ssh? Является ли какая-либо часть программного обеспечения X.org многопоточной? Указание параметров командной строки, разделенных запятыми, на основе строк текстовых файлов Что такое контейнер Linux и гипервизор Linux? Почему я получаю статус: Неизвестная работа в сервисе? Реализация расширенного регулярного выражения для добавления переменной числа ведущих нулей на основе позиции в строке KDE5 После возобновления приостановления я повредил ярлыки под значками Получите разницу между исходными файлами, установленными с apt и текущими файлами Как отключить респаун для терминала? Почему псевдоним работает иногда как nameref, а иногда нет? Как установить новый дистрибутив Linux на существующие зашифрованные разделы?

Ловушка Ctrl-C в awk-скрипте

Я считаю, что Ctrl- C может быть захвачен сценариями bash. Возможно ли также уловить его внутри сценария Awk для обработки этого события?

Например, для прерывания обработки, но распечатывая результаты уже обработанного, вместо того, чтобы просто замолчать?

Я не знаю о какой-либо реализации awk , которая поддерживает это. Вы могли бы написать расширение для gawk для этого , но здесь я предпочел бы перейти на другой язык.

perl упрощает преобразование awk скриптов с a2p скрипта 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 + C в 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}' )