Wpis z mikrobloga

Potrzebuję porady. Próbuję ogarnąć awk, ale średnio mi to idzie. Mam ścianę tekstu

---TRANSACTION 1234, not started
---TRANSACTION 5325, not started
---TRANSACTION 8706456, ACTIVE 849 sec
2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 26674, OS thread handle 0x7f2426942700,
---TRANSACTION 64363, not started

Zależy mi, żeby wyłapać aktywne transakcje, ale tylko aktywne - powiedzmy - powyżej 100 sekund. Jeśli znajdzie, ma wypluć kolejne 3 linie.
Na razie mam coś takiego:

./innodbcheck.sh | awk '/---TRANSACTION.*ACTIVE/{c=3}c&&c--'
daje:

---TRANSACTION 8706456, ACTIVE 849 sec
2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 26674, OS thread handle 0x7f2426942700,

Ale teraz chciałbym, żeby liczba między ACTIVE a sec była większa od 100 (na przykładzie powyżej 849). Jeśli tam będzie 99, to ma nie dopasować. 101 - ma wyprintować wszystkie 3 linie.

Jakby ktoś mógł mnie przynajmniej naprowadzić. Wiem, że muszę się jakoś odwołać do $4, ale nie mam pojęcia jak połączyć warunek z patternem :/

Mile widziane także jakieś przystępne tutoriale do awk, żeby stopniowo wprowadzały w ten program w stylu "od zera do bohatera" ;)

#linux #awk
  • 10
@RRybak: Bash/grep nie wygodniej?

$ grep -PA 3 "ACTIVE \d{3,}" plik
--- transaction 34534534, ACTIVE 849 sec
wes1
sdsd1
dasda1
--
--- transaction 34534534, ACTIVE 84932 sec
wwqde3
qas3
das3

-P włącza perla
-A 3 - pokaż 3 linie po (after) znaleziony string
\d - cyfry
{3,} - 3 i więcej

Plik:

$ cat plik
--- transaction 34534534, ACTIVE 849 sec
wes1
sdsd1
dasda1
asdas1
--- transaction 3434345, ACTIVE 38 sec
@no_one: hmm... jest to jakieś rozwiązanie. Tylko trochę sztywne. Gdy będę chciał dostosować długość transakcji, np. do 180 sekund, to będzie trzeba kombinować. Wiem, że awk ma możliwość porównywania wartości "matematycznie, czego nie zapewniają wyrażenia nieregularne.
Ale Twoje rozwiązanie będzie działało póki nie znajdę innego - dobrze wiedzieć, że grep też potrafi wypluć kilka linii (y).
@RRybak: ---TRANSACTION.*ACTIVE [0-9]{3,}, chciałem na początku odsiać samym regexem liczby min. 3 cyfrowe, ale widze, że chcesz konkretną liczbę porównywać
ale naiwnie zadziałało {if ($4 > 98) c=3} c&&c-- ( ͡° ͜ʖ ͡°)
$4 to po prostu pozycja po rozdzieleniu tekstu domyślnym separatorem
@jestem_w_szoku: tak!

awk '(/---TRANSACTION.*ACTIVE/ && $4>120) {c=3}c&&c--'
Kurde, nie wiem jak ja to pisałem, że mi na początku nie chciało działać :/ Okazuje się, że warunki się wstawia zwyczajnie i wygląda na to, że niepotrzebnie kombinowałem aż nadto.
Po drodze dołączyłem jeszcze sed żeby robił porządki z newline. Teraz działa.

Dzięki :)
@no_one: nooo, te testy to jest taki mój wstęp do zabaw skryptowych. "active 180" też by działało, bo w ogóle do dzisiaj nie wiedziałem, że grep może wypluć kilka linii. Ale docelowo chcę wyciągać wartości tych sekund, czyli w zależności czy jest to 120 czy 1000, to już będzie różnica czy "ostrzeżenie", czy "alarm". Dlatego jakoś tak uparłem się podszkolić z awk :)