2013-07-24 9 views
8

Mam skrypt awk, który sprawdza wiele możliwych wzorów, robiąc coś dla każdego wzorca. Chcę coś zrobić na wypadek, gdyby żaden z wzorów nie był dopasowany. czyli coś takiego:awk: "domyślna" akcja, jeśli nie został dopasowany żaden wzorzec?

/pattern 1/ {action 1} 
/pattern 2/ {action 2} 
... 
/pattern n/ {action n} 
DEFAULT {default action} 

Gdzie oczywiście linia „default” nie jest składnia awk i chciałbym wiedzieć, czy istnieje taka składnia (jak tam zwykle jest w sprawozdaniu swtich/Case w wielu językach programowania).

Oczywiście, zawsze mogę dodać polecenie "następny" po każdej czynności, ale jest to uciążliwe w przypadku, gdy mam wiele akcji, a co ważniejsze, uniemożliwia mi dopasowanie linii do dwóch lub więcej wzorów.

Odpowiedz

11

Można odwrócić mecz używając operatora negacji ! więc coś takiego:

!/pattern 1|pattern 2|pattern/{default action} 

Ale to dość nieprzyjemny dla n>2. Alternatywnie możesz użyć flagi:

{f=0} 
/pattern 1/ {action 1;f=1} 
/pattern 2/ {action 2;f=1} 
... 
/pattern n/ {action n;f=1} 
f==0{default action} 
1

Nie ma rozwiązania "bez konserwacji" dla DEFAULT-Branch w awk.

Pierwsza możliwość, którą zasugerowałbym, to uzupełnienie każdej gałęzi dopasowania wzoru o "następną" wypowiedź. To jest jak stwierdzenie przerwy. Dodaj ostatnią akcję na końcu, która pasuje do wszystkiego. Tak więc jest to gałąź DEAFULT.

Inną możliwością jest: ustawianie flagi dla każdego odgałęzienia, które ma dopasowanie do wzorca (tj. Twoje nie-domyślne gałęzie) np. rozpocznij swoje działania z NONDEFAULT = 1;

Dodaj ostatnią akcję na końcu (domyślna gałąź) i zdefiniuj warunek BRAK DOSKONAŁOŚCI == 0 instaed dopasowania wyrażenia reg.

+0

Pomijając błąd sugerujący użycie słowa "następny", różni się on od mojej odpowiedzi, w jaki sposób? –

+0

ooops - twoje prawo - przepraszam. – tue

7

GNU awk ma switch:

$ cat tst1.awk 
{ 
    switch($0) 
    { 
    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 

Alternatywnie z dowolnym 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 

użyć "break" lub "Dalej", jak/kiedy chcesz, podobnie jak w innych programowania Języki.

Albo, jeśli chcesz za pomocą flag

$ 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 

To nie exaclty same semantyka jako prawdziwy „default”, choć tak jak jest to zwyczaj, który może być mylące. Zwykle nie zalecałbym używania nazw zmiennych z dużymi literami, ale małe "domyślne" kłóciłoby się ze słowem kluczowym gawk, więc skrypt nie byłby przenośny do gawk w przyszłości.

0

Dość czyste, przenośny obejście używa if oświadczenie:

zamiast:

pattern1 { action1 } 

pattern2 { action2 }  
... 

można było użyć następujących:

{  
    if (pattern1) { action1 } 

    else if (pattern2) { action2 } 

    else { here is your default action } 
} 

Jak wspomniano powyżej, GNU awk ma Instrukcje switch, ale inne implementacje awk nie, więc użycie switcha nie byłoby przenośne.