Zgodnie z podręcznikiem awk, BEGIN i END nie są używane do dopasowania danych wejściowych, ale raczej do zapewnienia uruchomienia i wyczyszczenia -up do skryptu awk. Oto podany przykład:
ls -l | \ awk "BEGIN { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }" Files found: amd.conf antivir.conf xcdroast.conf xinetd.conf
Najpierw wypisuje łańcuch do wyjścia. Następnie sprawdza wejście pod kątem dopasowania do wzorca, gdzie wejście zaczyna się od znaku lub x, po którym następuje jeden lub wiele razy dowolny znak, po którym następuje .conf. W przypadku wszelkich dopasowań wypisywana jest dziewiąta kolumna.
Fakt, że musimy tutaj użyć początku, oznacza, że awk może użyć co najwyżej jednej funkcji wypisującej, która zawiera BEGIN lub END? Jeśli nie, to dlaczego nie możemy po prostu użyć funkcji drukowania na początku bez słowa kluczowego BEGIN? Wygląda na to, że BEGIN jest zbędne.
Komentarze
- Po prostu uruchomienie polecenia bez BEGIN odpowiedziałoby na twoje pytanie, pokazując, że ' nie jest zbędne i że otrzymasz inny wynik.
Odpowiedź
BEGIN
nie jest „t zbędne. Jeśli nie określisz „t BEGIN
, to print
zostanie wykonane dla każdego wiersza wejścia.
Cytowanie z instrukcja :
A
BEGIN
reguła jest wykonywana tylko raz, przed odczytaniem pierwszego rekordu wejściowego. Podobnie regułaEND
jest wykonywana tylko raz, po przeczytaniu całego wejścia.
$ seq 5 | awk "BEGIN{print "Hello"}/4/{print}" # Hello printed once Hello 4 $ seq 5 | awk "{print "Hello"}/4/{print}" # Hello printed for each line of input Hello Hello Hello Hello 4 Hello $
Odpowiedź
awk
przetwarza każdy wiersz danych wejściowych dla wyrażeń podanych w treści innej niż BEGIN
i END
bloki. W przypadku BEGIN
i END
bloki, awk
przetworzy instrukcje tylko raz, przed rozpoczęciem przetwarzania danych wejściowych i po zakończeniu przetwarzania danych wejściowych, odpowiednio wektywnie. Bez bloku BEGIN
nie tylko nie byłbyś w stanie wydrukować jednorazowych informacji, takich jak nagłówki, ale nie byłbyś w stanie efektywnie zainicjować niektórych zmiennych wymaganych przez treść. Do Twojej wiadomości, program awk
może mieć wiele bloków BEGIN
i END
.
Odpowiedź
awk
wykonuje każdy blok tylko wtedy, gdy poprzedni wzorzec pasuje. Pusty wzorzec (tylko blok) pasuje do każdej linii. BEGIN
i END
to specjalne wzorce pasujące do początku i końca pliku (analogiczne do znaczenia ^
i $
w kierunku poziomym).
Jeśli chcesz, aby coś zostało wykonane przed odczytaniem pliku, użyj BEGIN
. Na przykład inicjalizacja liczników czy coś. END
może następnie zebrać wyniki.
Odpowiedź
W podanym przykładzie co moim zdaniem jest uproszczone dla jasności pedagogicznej, masz rację, że jest zbędne. Możesz uzyskać te same wyniki bez użycia BEGIN
.
1 == NR { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }
dałoby takie same wyniki, ponieważ instrukcja print jest ograniczone do pierwszego wiersza danych wejściowych.
Biorąc to pod uwagę, bloki BEGIN
i END
są niezwykle potężne przybory. Jak wspomniały inne rozwiązania, możesz użyć bloku BEGIN
do inicjalizacji zmiennych lub innych procedur, które trzeba wykonać tylko raz, ale można ich również użyć do uruchamiania poleceń Awk, gdy nie ma pliki do przetworzenia. Prosty przykład:
BEGIN { print sqrt(12/4) }
Możesz zobaczyć bardziej poważny przykład programowania w Awk bez przetwarzania żadnych danych wejściowych tutaj .
Podobnie, blok END
jest niezwykle przydatny do wykonywania obliczeń i podsumowywania wszystkich danych wejściowych. Nie można tego zrobić (zwykle) bez uprzedniego wczytania wszystkich danych. Prosty przykład podsumowania danych wejściowych można znaleźć tutaj