Minulla on seuraava komento awk
, joka ottaa seuraavan syötetiedoston, input.txt
ja tuottaa alla olevan tuloksen. Voisiko joku käyttää aikaa selvittääksesi, miten tämä awk
-komentosarja toimii? Olen viettänyt siihen vähän aikaa, eikä sillä ole mitään järkeä.
Syöttö:
$ cat input.txt
FINISHED RSYNCJOBNA 20140502 0021 2182096 2082096 6 5 2014820905820902 10:02:15 2014820905820902 10:56:42 0:54:27 INITIATED RSYNCJOBNA 20140502 0022 3282096 3182096 6 5 2014820905820902 15:31:06 0:06:04 ce eque**
Tulos:
RSYNCJOBNA|0021|20140502|10:02:15|10:56:42|0:54:27|FINISHED RSYNCJOBNA|0022|20140502|15:31:06| |0:06:04|INITIATED
Komento saadaksesi yllä olevan ryhmän:
awk -v OFS="|" "/FINISHED|INITIATED/ { status = $1; getline; jobname = $1; getline; sequence = $2; date = $1; getline; start = $2; getline; if (status == "FINISHED") { end = $2; getline } else { end = " " } runtime = $1; print jobname, sequence, date, start, end, runtime, status; }" input.txt
Ymmärrän, että /FINISHED|INITIATED/ {}
tarkoittaa, että kiharoiden aaltosulkeiden sisällä olevat komennot suoritetaan vain linjoilla, jotka sopivat joko FINISHED
tai INITIATED
, mutta kuten sikäli kuin voin kertoa lähdöstä, komentosarja näyttää jäsentyvän kaikista riveistä. Mitä tapahtuu?
Kommentit
- Mitä et tarkalleen ymmärrä? Mikään ei? <
Siinä tapauksessa: Luetaanko awk-käyttöopas sinulle? Muuten: Ole tarkka. Tiedot luetaan muuttujiksi ja tuotetaan eri järjestyksessä.
/FINISHED|INITIATED/
, awk etsii vastaavaa riviä ja suorittaa operaation vain kyseisellä rivillä. Mutta operaatio suoritettiin kaikilla riveillä. Kuinka? vastaus
getline
-funktio lukee seuraavan rivin ja siirtää komentosarjan siihen. peräkkäiset getline
puhelut siirtyvät seuraavalle riville. Tämä on ehkä helpompi ymmärtää esimerkillä:
$ cat input.txt foo 1 2 $ awk "/foo/{print; getline; print; getline; print}" input.txt foo 1 2
Kuten Näet yllä, komentosarja käsittelee ensimmäisen rivin, koska se vastaa foo
. Jokainen puhelu numeroon getline
lukee rivin nykyisen jälkeen, joten seuraavat print
-puhelut tulostavat seuraavat rivit.
vastaus
Jos et tiedä mitä awk
-toiminto tekee, tavanomainen strategia on tarkastella man-sivua:
getline
Aseta $ 0 seuraavasta syötetietueesta; aseta NF, NR, FNR, RT
Komentolohko suoritetaan todellakin vain kahdesti. Muut rivit käsitellään getline
-palvelun kautta esto.
Tämä voidaan kirjoittaa uudestaan:
/FINISHED|INITIATED/ { status = $1; line_number=0; next; } { line_number++; } line_number==1 { jobname = $1; } line_number==2 { sequence = $2; date = $1; } ...
kommentit
- Mitä tapahtuu, jos seuraava tietue on tyhjä?
- @AvinashRaj Koodissasi tai vaihtoehdossani ei tarkastella rivien sisältöä (lukuun ottamatta
/FINISHED|INITIATED/
Linjat lasketaan vain alaspäin. Tiedot on järjestettävä tarkasti (awk parsista) ng perspektiivi) osoittamallasi tavalla, muuten koodi rikkoutuu.