Tôi tin rằng Ctrl- Ccó thể bị mắc kẹt trong các tập lệnh bash. Có phải cũng có thể nhốt nó bên trong một tập lệnh Awk để xử lý sự kiện đó không?
Ví dụ, để hủy bỏ xử lý, nhưng in kết quả của những gì đã được xử lý, thay vì chỉ bỏ đi?
Tôi tin rằng Ctrl- Ccó thể bị mắc kẹt trong các tập lệnh bash. Có phải cũng có thể nhốt nó bên trong một tập lệnh Awk để xử lý sự kiện đó không?
Ví dụ, để hủy bỏ xử lý, nhưng in kết quả của những gì đã được xử lý, thay vì chỉ bỏ đi?
Câu trả lời:
Tôi không biết về bất kỳ awk
triển khai nào có hỗ trợ cho việc đó. Bạn có thể viết một phần mở rộng cho gawk
điều đó , nhưng ở đây, tôi muốn chuyển sang ngôn ngữ khác.
perl
giúp dễ dàng chuyển đổi awk
các tập lệnh với a2p
tập lệnh của nó .
Chẳng hạn, nếu bạn có một đoạn awk
script như:
{count[$0]++}
END {
for (i in count) printf "%5d %s\n", count[i], i
}
a2p
trên đó sẽ cung cấp cho bạn một cái gì đó như:
#!/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;
}
Bạn có thể chỉnh sửa để thêm xử lý tín hiệu của mình (và loại bỏ việc xử lý các var=value
đối số mà chúng tôi không muốn ở đây và phần dành cho các hệ thống không hỗ trợ #!
):
#!/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;
Một cách khác có thể là làm gián đoạn việc cung cấp dữ liệu đến awk
và awk
bỏ qua SIGINT, như thay vì:
awk '{count[$0]++};END{for (i in count) printf "%5d %s\n", count[i], i}' file
làm:
cat file | (
trap '' INT
awk '{count[$0]++};END{for (i in count) printf "%5d %s\n", count[i], i}'
)
Ctrl+Csau đó sẽ giết cat
nhưng không được awk
. awk
vẫn sẽ tiếp tục xử lý đầu vào còn lại vẫn còn trong đường ống.
Để phát hiện Ctrl+Ctrong awk
, bạn có thể làm:
(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}'
)