Powiedzmy, że mam plik tekstowy taki jak:
R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242
Chcę użyć awk
do przetwarzania tych linii w inny sposób, na przykład
awk '/R1/ { print "=>" $0} /R2/ { print "*" $0} '
i chcę również wydrukować wszystkie pozostałe wiersze takimi, jakie są (bez tworzenia duplikatów już przetworzonych wierszy), w zasadzie potrzebuję znaku /ELSE/ { print $0}
na końcu mojej awk
linii.
Czy jest coś takiego?
awk
wdraża zwykłych podejrzanych, jeśli chodzi o warunki warunkowe. Warto stosowaćprintf
zamiastprint
pracy, którą chcesz wykonać podczas meczu.źródło
if-then-else
tego.next
jest ważnym narzędziem w programowaniu awk.printf
tutaj. Jego jedyną zaletą (chyba że robisz bardziej zaawansowane formatowanie niż konkatenacja) jest to, że nie dodaje on nowego wiersza, co nie jest tu istotne.print
musi jedynie wyświetlać dane wyjściowe,$0
podczas gdyprintf
musi analizować ciąg formatu.Chris Down pokazał już, w jaki sposób można uzyskać wyrażenie regularne za pomocą wyrażenia „jeśli” w bloku. Możesz uzyskać ten sam efekt także na inne sposoby, chociaż jego rozwiązanie jest prawdopodobnie lepsze.
Jednym z nich jest napisanie trzeciego wyrażenia regularnego, które będzie pasowało tylko do tekstu niepasującego do innych, w twoim przypadku wyglądałoby to mniej więcej tak:
Uwaga: używa to zakotwiczonych wyrażeń regularnych - ^ na początku wyrażeń regularnych będzie pasować tylko na początku wiersza - oryginalne wzorce tego nie zrobiły, co spowalnia nieco dopasowanie, ponieważ sprawdza wszystkie znaki w wierszu, a nie przeskakując do następnej linii. Trzeci przypadek („else”) będzie pasował do linii, która zaczyna się od znaku, który nie jest „R” ([^ R]) lub zaczyna się od „R”, po którym następuje znak, który nie jest „1” lub „ 2 '(R [^ 12]). Dwa różne znaczenia ^ są nieco mylące, ale ten błąd został popełniony dawno temu i nie zostanie zmieniony w najbliższym czasie.
Aby użyć uzupełniających wyrażeń regularnych, naprawdę muszą być zakotwiczone, ponieważ w przeciwnym razie [^ R] pasowałby np. 1 za nim. W przypadku bardzo prostych wyrażeń regularnych, takich jak Ty, takie podejście może być przydatne, ale gdy wyrażenia regularne stają się bardziej złożone, podejście to stanie się niemożliwe do zarządzania. Zamiast tego możesz użyć zmiennych stanu dla każdej linii, na przykład:
Ustawia się to na zero dla każdej nowej linii, a następnie na 1, jeśli pasuje do jednego z dwóch wyrażeń regularnych, i na koniec, jeśli wciąż jest zero, wykonuje wydruk 0 $.
źródło
rfile
powtórzono zaledwie 10000 linii zestawu danych pytającego.if (!handled)
Fuj! Użyj,next
aby przestać rozważać inne działania.if (!handled)
. Ogólne, elastyczne rozwiązania wielokrotnego użytku są dobre. Co jeśli kolejna osoba, która ma to pytanie, chce wykonać więcej przetwarzania po wydrukowaniu? Odpowiedzi znext
nie obsługują tego.