awk: действие" по умолчанию", если шаблон не был сопоставлен?
У меня есть скрипт awk, который проверяет множество возможных шаблонов, делая что-то для каждого шаблона. Я хочу, чтобы что-то было сделано в случае, если ни один из шаблонов не был сопоставлен. то есть что-то вроде этого:
/pattern 1/ {action 1}
/pattern 2/ {action 2}
...
/pattern n/ {action n}
DEFAULT {default action}
где, конечно, строка "DEFAULT" не является синтаксисом awk, и я хочу знать, есть ли такой синтаксис (как обычно есть в операторах swtich/case на многих языках программирования).
конечно, я всегда могу добавить команду "next" после каждого действия, но это утомительно, если у меня много действий, и, что более важно, это мешает мне сопоставить линию с двумя или более шаблонами.
4 ответов
вы можете инвертировать совпадение с помощью оператора отрицания !
что-то вроде:
!/pattern 1|pattern 2|pattern/{default action}
но это довольно неприятно для n>2
. В качестве альтернативы вы можете использовать флаг:
{f=0}
/pattern 1/ {action 1;f=1}
/pattern 2/ {action 2;f=1}
...
/pattern n/ {action n;f=1}
f==0{default action}
GNU awk имеет операторы переключения:
$ cat tst1.awk
{
switch()
{
case /a/:
print "found a"
break
case /c/:
print "found c"
break
default:
print "hit the default"
break
}
}
$ cat file
a
b
c
d
$ gawk -f tst1.awk file
found a
hit the default
found c
hit the default
альтернативно с любым awk:
$ cat tst2.awk
/a/ {
print "found a"
next
}
/c/ {
print "found c"
next
}
{
print "hit the default"
}
$ awk -f tst2.awk file
found a
hit the default
found c
hit the default
используйте "break" или "next" как/когда вы хотите, как и в других языках программирования.
или, если вам нравится, используя флаг:
$ cat tst3.awk
{ DEFAULT = 1 }
/a/ {
print "found a"
DEFAULT = 0
}
/c/ {
print "found c"
DEFAULT = 0
}
DEFAULT {
print "hit the default"
}
$ gawk -f tst3.awk file
found a
hit the default
found c
hit the default
это не точно такая же семантика, как истинный "по умолчанию", хотя это использование может ввести в заблуждение. Я бы обычно не выступал за использование всех имен переменных верхнего регистра, но нижний регистр "default" будет конфликтовать с ключевым словом gawk, чтобы скрипт не был переносимым для gawk в будущем.
нет решения "maintanance free" для ветви по умолчанию в awk.
первая возможность, которую я бы предложил, - это завершить каждую ветвь соответствия шаблону с помощью оператора "next". Это как заявление о перерыве. Добавьте последнее действие в конце, которое соответствует всему. Значит, это глухая ветвь.
другой возможностью: установите флаг для каждой ветви, которая имеет соответствие шаблону (т. е. ваши нестандартные ветви) например, начните свои действия с По умолчанию=1;
добавьте последнее действие в конце (ветвь по умолчанию) и определите условие NONDEFAULT==0 в соответствии с выражением reg.
довольно чистый, портативный обходной путь использует if
о себе:
вместо:
pattern1 { action1 }
pattern2 { action2 }
...
можно использовать следующие:
{
if ( pattern1 ) { action1 }
else if ( pattern2 ) { action2 }
else { here is your default action }
}
как упоминалось выше, GNU awk
имеет операторы switch, но другие awk
реализации не делают, поэтому использование коммутатора не будет портативным.