first, previous, next, last section, table of contents.


Bemeneti file-ok olvasása

A tipikus awk programokban a bemenet vagy a standard bemenet (általában a billentyűzet, de gyakran egy cső (pipe) valamilyen másik parancsból), vagy file-ok, amelyek nevét az awk parancssorában kell megadni. Az awk a bemeneti file-okat sorrendben olvassa be, és előbb befejezi az egyiket, mielőtt elkezdené a következőt. Az éppen aktuális file nevét a FILENAME (see section Beépített változók) beépített változóból lehet kiolvasni.

Az awk a bemenetet rekordokban olvassa be és dolgozza fel a programodban megadott szabályok szerint, egyszerre csak egyet. Alapesetben egy rekord egy sornak felel meg. Ezenkívül automatikusan minden rekordot feldarabol úgynevezett mezőkre, ezzel kényelmesebbé téve a rekord részeinek elérését a programod számára.

Ritkán, de előfordulhat, hogy a getline parancsot kell használnod. A getline parancs nagyon fontos része a nyelvnek, mivel adatot tud beolvasni bármilyen és bármennyi file-ból, ráadásul ezeket a file-okat nem kötelező megadni az awk parancssorában (see section Explicit beolvasás getline-al).

Hogyan történik a feldarabolás rekordokra

Az awk segédprogram a bemenetet rekordokra és mezőkre darabolja fel a programod számára. A rekordok egy úgynevezett rekordelválasztóval vannak elválasztva egymástól. Alapesetben a rekordelválasztó az új sor karakter. Ezért van az, hogy alapesetben egy sor megfelel egy rekordnak. Más karakter is megadható mint rekordelválasztó, ha az RS beépített változót beállítjuk a kívánt karakterre.

Az RS értékének megváltoztatása ugyanúgy történik mint bármilyen más változóé, az értékadó operátorral, `=' (see section Értékadó kifejezések). Az új rekordelválasztót idézőjelek közé kell tenni, mint egy szöveg konstanst. Általában az értékadást a legjobb azelőtt végrehajtani mielőtt bármilyen adatot a program feldolgozna, így minden adat a megfelelő elválasztó karakterrel lesz kezelve. Ehhez a BEGIN (see section A BEGIN és az END speciális minták) szabályt kell használni. Például:

awk 'BEGIN { RS = "/" } ; { print $0 }' BBS-list

megváltoztatja az RS értékét a "/" karakterre mielőtt bármilyen adatot beolvasna, így a rekordelválasztó karakter a "/" lesz. Ezután elkezdi olvasni a file tartalmát és az awk program második szabályát alkalmazza (tevékenységet minta nélkül), ami kinyomtat minden rekordot. Mivel a print kifejezés minden kinyomtatott rekordhoz egy új sort ad, a program lényegében a bemenetet a kimenetre másolja át úgy, mintha minden "/" karaktert lecserélnénk egy új sor karakterre. Az eredmény a `BBS-list' file-al:

$ awk 'BEGIN { RS = "/" } ; { print $0 }' BBS-list
-| aardvark     555-5553     1200
-| 300          B
-| alpo-net     555-3412     2400
-| 1200
-| 300     A
-| barfly       555-7685     1200
-| 300          A
-| bites        555-1675     2400
-| 1200
-| 300     A
-| camelot      555-0542     300               C
-| core         555-2912     1200
-| 300          C
-| fooey        555-1234     2400
-| 1200
-| 300     B
-| foot         555-6699     1200
-| 300          B
-| macfoo       555-6480     1200
-| 300          A
-| sdace        555-3430     2400
-| 1200
-| 300     A
-| sabafoo      555-2127     1200
-| 300          C
-|

Érdemes megfigyelni, hogy a `camelot' kezdetű sor nem lett feldarabolva. Az eredeti file-ban (see section Adat file-ok a példákhoz) a sor így néz ki:

camelot      555-0542     300               C

Csak egyetlen baud érték van megadva és nincs "/" karakter a sorban.

Egy másik lehetőség a rekordelválasztó megváltoztatására a parancssor használata (see section Other Command Line Arguments).

awk '{ print $0 }' RS="/" BBS-list

Ez a parancssor beállítja az RS változót a `/' karakterre, mielőtt elkezdené a `BBS-list' file feldolgozását.

A speciális karakter, mint a `/' karakter használata az esetek legnagyobb részében nem okoz problémát, de a következő speciális parancssor csak egy meglepő `1'-est nyomtat ki. Az NF beépített változó értéke az aktuális rekordon belüli mezők számát adja meg. Jelen esetben egyetlen mező van, ami az új sor karaktert tartalmazza.

$ echo | awk 'BEGIN { RS = "a" } ; { print NF }'
-| 1

Amint eléri a bemenet végét a jelenlegi rekordot lezárja, még akkor is ha az utolsó karakter a file-ban nem a rekordelválasztó volt (s.s.).

Az üres szövegnek, "" (szöveg, amiben nincs karakter), mint az RS értéke, speciális jelentése van: azt jelenti, hogy a rekordok egy vagy több üres sorral vannak elválasztva és semmi mással. See section Több sorból álló rekordok, további részletekért.

Ha az RS értékét az awk futása közben változtatod meg, akkor az új értéket csak az új rekord beolvasásától kezdve veszi figyelembe, az éppen aktuális (és az előzőleg feldolgozott) rekordokat nem befolyásolja.

Miután megtalálta a rekord végét, a gawk az RT változót beállítja arra a karakterre/szövegre, ami illeszkedett az RS rekordelválasztóra.

Valójában az RS értéke nem csak egy karakter lehet, hanem bármilyen reguláris kifejezés (see section Reguláris kifejezések). Általában egy rekord a megadott reguláris kifejezés kezdeténél végződik; a következő rekord az illeszkedő reguláris kifejezés végénél kezdődik. Ez a szabály érvényesül alapesetben is, amikor az RS az új sor karakter: a rekord a következő illeszkedő reguláris kifejezésnél ér véget (az új sor karakternél), a következő rekord pedig a reguláris kifejezés végénél kezdődik (vagyis a következő sor első karakterénél). Mivel az új sor karakter illeszkedik az RS-re ezért egyik rekordnak sem része.

Amikor az RS értéke csak egy karakter, akkor az RT is ugyanazt a karaktert fogja tartalmazni. Ugyanakkor, ha az RS értéke egy reguláris kifejezés az RT sokkal hasznosabb lehet; azt az aktuális szövegrészletet tartalmazza, ami illeszkedett a reguláris kifejezésre.

A fentieket az alábbi példa illusztrálja, ahol az RS egy olyan reguláris kifejezés amelyik vagy az új sor karakterre vagy egy olyan szövegre illeszkedik, amely egy vagy több nagybetűt tartalmaz, ill. előtte és/vagy mögötte egy szóköz karakter lehet (see section Reguláris kifejezések).

$ echo record 1 AAAA record 2 BBBB record 3 |
> gawk 'BEGIN { RS = "\n|( *[[:upper:]]+ *)" }
>             { print "Record =", $0, "and RT =", RT }'
-| Record = record 1 and RT =  AAAA 
-| Record = record 2 and RT =  BBBB 
-| Record = record 3 and RT = 
-|

Az utolsó sor egy üres sor. Ez azért van, mert az utolsó RT értéke egy új sor és a print kifejezés mindig hozzáad egy lezáró új sor karaktert a kimenethez.

See section A Simple Stream Editor, ahol további példák találhatók az RS és RT használatára.

Az RS használata mint reguláris kifejezés és az RT változó az awk nyelv gawk kiegészítései; "compatibility" módban nem használhatók (see section Command Line Options). "Compatibility" módban az RS-nek csak az első karakterét használja a rekord végének megállapítására.

Az awk segédprogram azt is számontartja, hogy eddig hány darab rekordot olvasott be az aktuális bemeneti file-ból. Ezt az értéket az FNR beépített változóban lehet megtalálni. Amikor egy új file-t kezd el olvasni a változó értéke mindig lenullázódik. Egy másik beépített változó, az NR, az összes file-ból az összes eddig beolvasott rekordok számát tárolja. Kezdeti értéke zérus és soha nem nullázódik le automatikusan.

Mezők elérése

A beolvasott rekordot az awk automatikusan feldarabolja mezőkre. Alapesetben a mezőket szóközök vagy tab vagy új sor karakterek(6) választják el, mint a szavakat egy mondatban; hasonló karakterek, mint lapdobás (formfeed) nem szolgálnak elválasztóként az awk-ban.

A mezők célja, hogy kényelmesebbé tegyék számodra a rekordok feldolgozását. Nem kötelező őket használni -- dolgozhatsz csak a rekorddal -- de a mezők teszik az awk programokat igazán hasznossá.

Az awk programban egy mezőre egy dollár jellel, `$', és az utána következő számmal lehet hivatkozni. Így, a $1 az első, a $2 a második mezőre utal. Vegyük a következő sort:

This seems like a pretty nice example.

Itt az első mező vagy $1 a `This'; a második mező vagy $2 a `seems' és így tovább. Az utolsó mező vagy $7 az `example.'. Mivel nincs szóköz a utolsó `e' betű és a lezáró `.' pont között ezért a pont a mező része lesz.

Az NF beépített változó adja meg, hogy az aktuális rekordban hány mező van. Az awk automatikusan frissíti az NF értékét minden új rekord beolvasásánál.

Akárhány mező van a rekordban, az utolsó rekordra a $NF-el is lehet hivatkozni. Így a fenti példában az $NF ugyanaz lenne mint a $7, ami az `example.'. Hogy ez miért működik, azt egy kicsit később magyarázzuk el. Ha az utolsó utáni mezőre hivatkozol, például a $8-ra amikor csak hét mező van a rekordban, egy üres szöveget kapsz eredményül.

A $0 egy speciális eset, a teljes rekordot reprezentálja. $0-t használhatod ha a mezőkkel nem akarsz foglalkozni.

Még egy példa:

$ awk '$1 ~ /foo/ { print $0 }' BBS-list
-| fooey        555-1234     2400/1200/300     B
-| foot         555-6699     1200/300          B
-| macfoo       555-6480     1200/300          A
-| sabafoo      555-2127     1200/300          C

Ez a példa minden olyan rekordot kinyomtat a `BBS-list' file-ból, amelynek az első mezőjében előfordul a `foo' szó. A `~' operátor az illesztő operátor (see section Hogyan használjuk a reguláris kifejezéseket); azt ellenőrzi, hogy a megadott kifejezés (itt a $1 mező) illeszkedik-e a reguláris kifejezésre.

Ezzel ellentétben, a következő példa a `foo' szót keresi a teljes rekordban és csak az első és az utolsó mezőt nyomtatja ki az illeszkedő rekordoknál.

$ awk '/foo/ { print $1, $NF }' BBS-list
-| fooey B
-| foot B
-| macfoo A
-| sabafoo C

Nem konstans mezőazonosító számok

A mezőazonosító szám nem csak konstans lehet. Az awk nyelvben a `$' karakter után bármilyen kifejezés állhat. A kifejezés értéke adja meg a mező számát. Ha kifejezés értéke szöveg, akkor azt átalakítja számmá. Például:

awk '{ print $NR }'

Ha emlékszem, akkor az NR az eddig beolvasott rekordok számát tartalmazza; az első rekordnál egy, a másodiknál kettő, és így tovább, az értéke. Így ez a példa kinyomtatja az első mezőt az első rekordnál, a második mezőt a második rekordnál, és így tovább. A huszadik rekordnál a huszadik mezőt nyomtatja ki; de mivel valószínűleg a rekordban nincs 20 mező ezért csak egy üres sort fog kinyomtatni.

Itt egy másik példa, ahol egy kifejezést használunk a mezőazonosító számnak:

awk '{ print $(2*2) }' BBS-list

Az awk először kiértékeli a `(2*2)' kifejezést, majd az eredményül kapott számot használja a mező azonosítására. A `*' jel szorzást jelent, így a `2*2' kifejezés értéke négy lesz. A zárójelek azért kellenek, hogy előbb a szorzás hajtódjon végre és csak utána a mező azonosítás; zárójelek mindig kellenek, ha matematikai műveletet használunk a mezőazonosító szám előállítására. Végül is ez a példa a `BBS-list' file minden sorából a negyedik mezőt fogja kinyomtatni. (Az awk nyelv operátorainak a precedencia listája, csökkenő sorrendben a section Operátorok precedenciája (Hogyan ágyazhatók operátorok egymásba) alatt található meg.)

Ha a mezőazonosító szám a kiértékelés után zérus lesz, akkor a teljes rekordot kapod eredményül. Így a $(2-2) kifejezés ugyanaz mint a $0. Negatív számok nem megengedettek mezőazonosítóként; ha mégis előfordulna, akkor valószínűleg az awk program leáll. (A POSIX szabvány nem definiálja a viselkedést negatív szám esetére. A gawk leállítja a programot negatív szám esetén, más awk implementációk másképp viselkedhetnek.)

Ahogy azt korábban elmondtuk, section Mezők elérése, az NF beépített változó (see section Beépített változók) a mezők számát adja meg az aktuális rekordban. Így a $NF kifejezés nem egy speciális kifejezés, csak a közvetlen következménye az NF használatának, mint mezőazonosító szám.

Mező tartalmának megváltoztatása

Egy mező tartalmát meg is változtathatod a programon belül. (Bár ez a bemenetet megváltoztatja az awk számára, valójában a tényleges bemenet változatlan; az awk soha nem módosítja a bemeneti file-t.)

Vegyük a következő példát és a kimenetét:

$ awk '{ $3 = $2 - 10; print $2, $3 }' inventory-shipped
-| 13 3
-| 15 5
-| 15 5
...

A `-' jel a kivonás, így ez a program a harmadik mezőnek, $3, új értéket ad, a második mezőből tizet vonva ki, `$2 - 10'. (See section Matematikai operátorok.) Ezután a második és a harmadik mezőt kinyomtatja az új értékkel.

Ahhoz, hogy ez működjön, a második mezőnek, $2, olyan szöveget kell tartalmaznia, ami egy értelmes szám; a szöveget átalakítja számmá, hogy a matematikai műveletet elvégezhesse. A kivonás eredményét átalakítja szöveggé, amit végül hozzárendel a harmadik mezőhöz. See section Szövegek és számok konverziója.

Amikor egy mező tartalmát megváltoztatod, az awk a rekord szövegét újra kiértékeli, hogy a rekord tükrözze a változást. Így a $0 a megváltozott mezőt fogja tartalmazni. A következő program a bemeneti file-t nyomtatja ki úgy, hogy minden sorban a második mező értékéből tizet kivon.

$ awk '{ $2 = $2 - 10; print $0 }' inventory-shipped
-| Jan 3 25 15 115
-| Feb 5 32 24 226
-| Mar 5 24 34 228
...

Olyan mezőkhöz is rendelhető tartalom, amelyek nem részei a rekordnak. Például:

$ awk '{ $6 = ($5 + $4 + $3 + $2)
>        print $6 }' inventory-shipped
-| 168
-| 297
-| 301
...

A $6 nem létezik a rekordban, mi hoztuk létre és a $2, $3, $4 és a $5 mezők tartalmának összegével töltöttük fel. A `+' jel összeadást jelent. Az `inventory-shipped' file esetén a $6 mező az egy hónapban elküldött összes csomag számát jelenti.

Egy új mező létrehozása esetén, a bemeneti rekord belső reprezentációja is megváltozik -- a $0 értéke. Így a mező létrehozása után egy `print $0' kifejezés kinyomtatja a rekordot az új mezővel együtt, a megfelelő mezőelválasztót használva.

A rekord új kiértékelése befolyásolni fogja az NF értékét (a mezők száma; see section Mezők elérése), ugyanakkor az NF és az eddig nem tárgyalt kimeneti mezőelválasztó, OFS (see section Kimeneti elválasztó) is befolyásolva lesz a kiértékelés által. Például az általad létrehozott legnagyobb mezőazonosító számot fogja az NF tartalmazni.

Ugyanakkor csak egy egyszerű hivatkozás egy olyan mezőre, ami nem szerepel a rekordban, nem fogja megváltoztatni sem a $0 sem az NF értékét. A hivatkozás egy üres szöveget fog generálni, például:

if ($(NF+1) != "")
    print "can't happen"
else
    print "everything is normal"

program részlet az `everything is normal' szöveget fogja kinyomtatni, mivel a NF+1-ik mező természetesen nem szerepel a rekordban. (Az awk if-else kifejezésről további információ a see section Az if-else kifejezés alatt található. A `!=' operátorról pedig a section Változó típusok és az összehasonlító kifejezések ad további információt.)

Fontos megjegyezni, hogy egy létező mező tartalmának megváltoztatása befolyásolni fogja a $0 értékét, de nem fogja megváltoztatni NF értékét, még akkor sem ha a mező új értéké az üres szöveg. Például:

$ echo a b c d | awk '{ OFS = ":"; $2 = ""
>                       print $0; print NF }'
-| a::c:d
-| 4

A mező még mindig ott van; csak éppen üres, amit a két egymást követő kettőspont is jelez.

Ez a példa bemutatja, hogy mi történik, ha egy új mezőt hozunk létre.

$ echo a b c d | awk '{ OFS = ":"; $2 = ""; $6 = "new"
>                       print $0; print NF }'
-| a::c:d::new
-| 6

A közbenső, $5 mező is létrejön egy üres szöveggel (a második dupla kettőspont mutatja) és az NF értékét hatra állítja.

Végül, ha az NF értékét csökkentjük, akkor mező(ke)t dobunk el és a $0 új értéket kap a kiértékelés után. Például:

$ echo a b c d e f | ../gawk '{ print "NF =", NF; 
>                               NF = 3; print $0 }'
-| NF = 6
-| a b c

Hogyan történik a mezőelválasztás

Ez a fejezet egy kicsit hosszabb lesz, mivel az awk egyik alapvető működési elvét magyarázza el.

A mezőelválasztás alapjai

A mezőelválasztó, vagy egy karakter vagy egy reguláris kifejezés, adja meg, hogy az awk hogyan darabolja fel a bemeneti rekordot mezőkre. Az awk a mezőelválasztóra illeszkedő karaktersorozatokat keres a bemeneti rekordban és a mezők azok a szövegek lesznek amelyek az illeszkedő részek között helyezkednek el.

Az alábbi példákban a szóköz helyett a "*" jelet fogjuk használni a kimenetben.

Ha a mezőelválasztó az `oo', akkor az alábbi sor:

moo goo gai pan

az `m', `*g' és a `*gai*pan' mezőkre lesz feldarabolva. A második és a harmadik mező előtti szóköz is a mező része lesz.

A mezőelválasztót az FS beépített változó tartalmazza. Shell programozók figyelem! Az awk nem használja az IFS nevet, amit a POSIX szabványos shell-ek használnak (Bourne shell, sh, vagy a GNU Bourne-Again Shell, Bash).

Egy awk programon belül az FS értékét az `=' értékadó operátorral változtathatod meg (see section Értékadó kifejezések). A legjobb alkalom erre a program eleje, mielőtt bármilyen adatot a program beolvasna, így a legelső rekord is a megfelelő mezőelválasztóval lesz feldolgozva. Például a BEGIN minta (see section A BEGIN és az END speciális minták) használatával teheted ezt meg. Az alábbi példában az FS értéke a "," lesz:

awk 'BEGIN { FS = "," } ; { print $2 }'

és ha a bemeneti sor:

John Q. Smith, 29 Oak St., Walamazoo, MI 42139

akkor az awk program a `*29*Oak*St.' szöveget fogja kinyomtatni.

Előfordul, hogy az adatod olyan helyen is tartalmaz elválasztó karaktert, ahol azt nem várnád. Például személy nevek esetén a fenti példa sorban tudományos cím vagy egyéb adat is megadható, mint `John Q. Smith, LXIX'. Tehát:

John Q. Smith, LXIX, 29 Oak St., Walamazoo, MI 42139

sor esetén a program a `*LXIX'-et fogja kinyomtatni és nem a `*29*Oak*St.'. Ha a lakcímeket szeretted volna kigyűjteni, természetesen meglepődnél. A tanulság az, hogy az adatstruktúrát és az elválasztó karaktereket gondosan kell megválasztani, hogy az ilyen problémák elkerülhetők legyenek.

Amint azt tudod, alapesetben a mezőket szóközök, tab és új sor karakterek választják el egymástól; nem csak egy szóköz: két szóköz egymás után nem generál egy üres mezőt. Az FS alapértéke a " ", egy szóközt tartalmazó szöveg. Ha ezt a normális módon értelmeznénk, minden szóköz egy mezőt választana el, így két szóköz egymás után egy üres mezőt generálna. Az ok amiért nem ez történik az, hogy egyetlen szóköz mint az FS értéke egy speciális eset.

Ha az FS bármilyen más karaktert tartalmaz, pl. a ",", akkor a karakter minden előfordulása két mezőt választ el egymástól. Két egymás utáni megjelenése egy üres mezőt határol. Ha egy rekord elején vagy végén fordul elő, az is üres mezőt jelent. A szóköz karakter az egyetlen kivétel, ami nem követi ezt a szabályt.

Reguláris kifejezések mint mezőelválasztók

Az előző alfejezet bemutatta egy karakter használatát mint mezőelválasztó. Általánosítva, az FS értéke bármilyen reguláris kifejezés lehet. Ebben az esetben, minden illeszkedés a rekordon belül két mezőt választ el egymástól. Például:

FS = ", \t"

esetén minden olyan szöveg, ami egy vesszőből, egy szóköz és egy tab karakterből áll, elválaszt két mezőt. (`\t' egy escape szekvencia (see section Escape szekvenciák), ami a tab karaktert helyettesíti.)

Egy kicsit bonyolultabb példa: tegyük fel, hogy a szóköz karaktert ugyanúgy szeretnéd használni, mint más karaktereket a mezők elválasztására. Ebben az esetben az FS-t a "[ ]" reguláris kifejezésre kell beállítani (nyitó szögletes zárójel, szóköz, záró szögletes zárójel). Ez a reguláris kifejezés csak egy szóközre illeszkedik és semmi másra (see section Reguláris kifejezések).

Van egy fontos különbség a `FS = " "' és a `FS = "[ \t\n]+"' kifejezések között. Mindkét esetben a mezőket egy vagy több szóköz, tab és/vagy új sor karakter választja el, de amikor az FS értéke a " ", az awk először levágja a kezdő és záró szóközöket, tab és új sor karaktereket és csak utána kezdi el feldolgozni a rekordot.

Az alábbi példa csak egy `b'-t fog kinyomtatni:

$ echo ' a b c d ' | awk '{ print $2 }'
-| b

de ez egy `a'-t nyomtat ki (extra szóközök vannak a betűk körül):

$ echo ' a  b  c  d ' | awk 'BEGIN { FS = "[ \t]+" }
>                                  { print $2 }'
-| a

Ebben az esetben az első mező üres.

A kezdő és záró szóköz, tab és új sor karakterek levágása a $0 új kiértékelésénél is fontos szerepet játszik, így:

$ echo '   a b c d' | awk '{ print; $2 = $2; print }'
-|    a b c d
-| a b c d

Az első print kifejezés kinyomtatja az eredeti rekordot. A $2 mező értékadása után újraértékeli a $0 tartalmát; a $1-tól az $NF-ig a mezőket összefűzi az OFS tartalmát használva elválasztásra. Mivel a kezdő és záró szóköz karaktereket nem vette figyelembe a $1 megállapításánál, így azok most sem részei az új $0-nak. Végül az utolsó print kifejezés kiírja az $0 új tartalmát.

Minden karakter egy mező

Előfordulhat, hogy egy rekord minden karakterét meg szeretnéd vizsgálni külön-külön. gawk-ban ez egyszerű, egy üres szöveget ("") kell az FS-hez rendelni. Ebben az esetben minden karakter egy önálló mező lesz:

$ echo a b | gawk 'BEGIN { FS = "" }
>                  { 
>                      for (i = 1; i <= NF; i = i + 1)
>                          print "Field", i, "is", $i
>                  }'
-| Field 1 is a
-| Field 2 is
-| Field 3 is b

Hagyományosan, ha az FS értéke "", akkor az awk viselkedése nem definiált. Ebben az esetben a Unix awk az egész rekordot egy mezőnek tekinti (s.s.). "Compatibility" módban (see section Command Line Options), ha az FS értéke "" a gawk is így viselkedik.

Az FS beállítása parancssorból

Az FS értéke a parancssorból is beállítható, a `-F' opció használatával:

awk -F, 'program' input-files

hatására az FS értéke a `,' karakter lesz. Fontos észrevenni, hogy az opciót a nagy `F' betűvel lehet megadni, míg a kis `f' betű az awk programot tartalmazó file-t adja meg. A `-F' és `-f' -nek semmi köze egymáshoz, a kis- és nagybetű megkülönböztetés fontos. Természetesen a két opciót használhatod egyszerre.

A `-F' utáni argumentum feldolgozása ugyanúgy történik mintha az FS-t a programban állítanánk be. Ez azt jelenti, hogy ha a mezőelválasztó egy speciális karaktert tartalmaz, akkor azt megfelelően védeni kell a `\' karakterrel. Például ha a mezőelválasztó egy `\' karakter, akkor ezt kell begépelni:

# ugyanaz mint FS = "\\" 
awk -F\\\\ '...' files ...

Mivel a `\' karakter a shell számára is speciális karakter, ezért az awk csak a `-F\\' kifejezést fogja megkapni. Ezután az awk feldolgozza a `\\' escape szekvenciát (see section Escape szekvenciák), ami végül a `\' jelet adja meg mint mezőelválasztó.

Egy speciális eset, ha "compatibility" módban (see section Command Line Options) az `-F' után csak egy `t' betű áll. Ekkor az FS valójában a tab karaktert kapja értékül. Ez azért van, mert ha a `-F\t' gépeled be idézőjelek nélkül, akkor a `\' jelet a shell eldobja és az awk azt gondolja, hogy a tab karaktert akartad megadni és nem a `t' betűt, mint mezőelválasztó. Ha tényleg csak a `t' betűvel akarod elválasztani a mezőket, akkor a `-v FS="t"' kifejezést kell használni (see section Command Line Options).

Például készítsünk egy `baud.awk' nevű file-t, ami a /300/ mintát és a `print $1' tevékenységet tartalmazza:

/300/   { print $1 }

Állítsuk be az FS-t a `-' karakterre, majd futtassuk a programot a `BBS-list' file-al. Az alábbi parancs kilistázza azoknak a gépeknek a nevét és a telefonszámuk első három jegyét, amelyek 300 baud-al működnek:

$ awk -F- -f baud.awk BBS-list
-| aardvark     555
-| alpo
-| barfly       555
...

A második sor nem egészen tökéletes. Az eredeti file-ban (see section Adat file-ok a példákhoz) így nézett ki:

alpo-net     555-3412     2400/1200/300     A

A `-' karakter szerepel a rendszer nevében, így nem a telefonszámot írja ki, ahogy azt szeretnénk. Ez is mutatja mennyire fontos, hogy gondosan válasszuk meg a mezőket és a mezőelválasztókat.

A Unix rendszereken a jelszó (passwd) file-ban minden felhasználóhoz tartozik egy bejegyzés (egy sor). A mezők kettősponttal vannak elválasztva. Az első mező a bejelentkezési név, a második a felhasználó jelszava. (A legtöbb rendszeren ma már nem elérhető a jelszó a felhasználók számára.) Egy bejegyzés így nézhet ki:

arnold:xyzzy:2076:10:Arnold Robbins:/home/arnold:/bin/sh

Az alábbi program végignézi a jelszó file-t és kilistázza azokat a felhasználókat akiknél nincs jelszó megadva:

awk -F: '$2 == ""' /etc/passwd

Összefoglalás a rekordok mezőkre darabolásáról

A POSIX szabvány szerint az awk-nak úgy kell viselkednie, mintha minden rekordot a beolvasás során darabolna fel mezőkre. Ez azt jelenti, hogy ha megváltoztatod az FS értékét miután a rekordot beolvasta, akkor a mezők feldarabolása azt az állapotot kell tükrözze, ami a régi FS használatával érvényes.

Ugyanakkor sok awk implementáció nem így működik. Ezek a programok csak akkor darabolják fel a a rekordot mezőkre, amikor hivatkoznak egy mezőre, így a mezők az éppen aktuális FS mezőelválasztó szerint lesznek megállapítva. (s.s.) Ezt a viselkedést nehéz felfedezni. Az alábbi program illusztrálja a különbséget a két megoldás között. (A sed(7) parancs a `/etc/passwd' file-nak csak az első sorát nyomtatja ki.)

sed 1q /etc/passwd | awk '{ FS = ":" ; print $1 }'

Egy rossz awk implementáció esetén a program a

root

sort nyomtatja ki, míg a gawk valami ehhez hasonlót fog kiírni:

root:nSijPlPhZZwgE:0:0:Root:/:

Az alábbi táblázat összefoglalja, hogy az FS értékétől függően a mezők hogyan lesznek elválasztva . (A `==' jelentése egyenlő.)

FS == " "
A mezőket szóközök, tab és új sor karakterek határolják. Ha a rekord elején vagy végén szerepelnek, akkor nem lesznek figyelembe véve. Ez az alapbeállítás.
FS == egy bármilyen karakter
A mezőket az adott karakter választja el. Ha egymás után fordulnak elő, akkor egy üres mezőt határolnak. Ha a rekord legelején vagy legvégén egy ilyen karakter előfordul akkor az első vagy az utolsó mező egy üres mező lesz. A karakter akár speciális reguláris kifejezés operátor karakter is lehet; nem kell `\' jel elé.
FS == regexp
A mezőket olyan karaktersorozatok választják el, amelyek illeszkednek a regexp reguláris kifejezésre. A rekord elején vagy végén előforduló illeszkedő kifejezés hatására az első vagy az utolsó mező egy üres mező lesz.
FS == ""
A rekord minden karaktere egy önálló mező.

Meghatározott szélességű adatok beolvasása

(Ezt a fejezetet kezdő felhasználók nyugodtan átugorhatják első olvasásnál, mivel az itt leírt programozási lehetőség csak kísérleti, és bonyolult lehet megérteni.)

A gawk 2.13-as verziója vezette be azt a megoldást, amivel adott szélességű mezőket lehet kezelni, és nincs mezőelválasztó. Régi FORTRAN programok bemeneteként fordulhat elő ilyen adat, ahol a számok között nincs elválasztás.

Lényegében egy olyan táblázatról beszélünk, ahol az oszlopok szóközökkel vannak igazítva és az üres mező csak egy szóköz. Ilyen környezetben az awk mezőelválasztó stratégiája nem igazán tökéletes. Habár egy hordozható program a substr függvény használatával meg tudja oldani a problémát (see section Szövegmanipuláló beépített függvények), a megoldás nem túl szép és különösen nem lenne hatékony sok rekord esetén.

A rekord adott szélességű mezőkre darabolásához a FIELDWIDTHS beépített változónak kell egy olyan szöveget megadni, ahol a szövegben a mezők szélességét jelentő számokat szóközök választanak el. Minden szám egy mező szélességét adja meg, a mezők közti szóközöket is beleszámolva. Ha bizonyos oszlopokkal nem akarsz foglalkozni, akkor definiáld egy külön mezőbe a szélesség megadásával, majd ne vedd figyelembe a keletkezett mezőt.

Az alábbi adatsor a w Unix segédprogram kimenete és alkalmas a FIELDWIDTHS használatának bemutatására.

 10:06pm  up 21 days, 14:04,  23 users
User     tty       login  idle   JCPU   PCPU  what
hzuo     ttyV0     8:58pm            9      5  vi p24.tex 
hzang    ttyV3     6:37pm    50                -csh 
eklye    ttyV5     9:53pm            7      1  em thes.tex 
dportein ttyV6     8:17pm  1:47                -csh 
gierd    ttyD3    10:00pm     1                elm 
dave     ttyD4     9:47pm            4      4  w 
brent    ttyp0    26Jun91  4:46  26:46   4:41  bash 
dave     ttyq4    26Jun9115days     46     46  wnewmail

Az alábbi program a fenti adatból kiválogatja az üresjárati (idle) időtartam hosszát, átkonvertálja másodpercbe, majd kiírja az első két mezőt és az üresjárati időt másodpercben. (A program olyan megoldásokat is tartalmaz, amiket eddig nem tárgyaltunk.)

BEGIN  { FIELDWIDTHS = "9 6 10 6 7 7 35" }
NR > 2 {
    idle = $4
    sub(/^  */, "", idle)   # strip leading spaces
    if (idle == "")
        idle = 0
    if (idle ~ /:/) {
        split(idle, t, ":")
        idle = t[1] * 60 + t[2]
    }
    if (idle ~ /days/)
        idle *= 24 * 60 * 60
 
    print $1, $2, idle
}

Az eredmény:

hzuo      ttyV0  0
hzang     ttyV3  50
eklye     ttyV5  0
dportein  ttyV6  107
gierd     ttyD3  1
dave      ttyD4  0
brent     ttyp0  286
dave      ttyq4  1296000

Egy másik (talán praktikusabb) példa a szavazókártyák feldolgozása. Az USA egyes területein úgy kell szavazni, hogy lyukat kell ütni egy kártyába. Ezeket a kártyákat használjak a szavazatszámlálás során. Mivel az is előfordulhat, hogy valaki az adott kérdésben nem akar szavazni egyes oszlopok üresek lehetnek. Az ilyen adatok feldolgozására az gawk jól használhatná a FIELDWIDTHS megoldást. (Persze az egy másik kérdés, hogy a gawk hogyan kerülne a kártyaolvasó gépbe!)

Ha értéket adunk az FS változónak a gawk visszatér az eredeti mező darabolási metódushoz. Mivel valószínűleg nem akarod tudni az FS értékét, csak visszakapcsolni normál módba, használhatod a `FS = FS' kifejezést is.

Ez a lehetőség még csak kísérleti, idővel változhat. Figyelj oda, mert a gawk egyáltalán nem ellenőrzi a FIELDWIDTHS-nek megadott értékeket.

Több sorból álló rekordok

Ha egy adatbázisban egy sor nem tudja kényelmesen tárolni az összes információt, akkor több soros rekordot érdemes használni.

Az első lépés a megfelelő adatformátum kiválasztása: hogyan definiálsz egy rekordot? Mi választja el a rekordokat?

Az egyik megoldás valamilyen szokatlan karakter vagy szöveg használata rekordelválasztóként. Például használhatod a lapdobás (formfeed) karaktert (`\f' az awk-ban mint a C programozási nyelvben is), így minden rekord egy oldal a file-ban. Ehhez csak az RS változót kell az "\f"-re beállítani (egy olyan szövegre, ami csak a a lapdobás karaktert tartalmazza). Bármilyen más karakter is megfelelő, ha biztos vagy benne, hogy nem fog a rekordon belül előfordulni.

A másik megoldás, hogy üres sorok választják el a rekordokat. Ha az RS értéke egy üres szöveg, akkor a rekordokat egy vagy több üres sor választhatja el. Ebben az esetben a rekord mindig az első üres sornál ér véget, és a következő rekord az első nem üres sornál kezdődik - nem számít, hogy hány üres sor van a két rekord között, mindig egy elválasztóként lesznek kezelve.

Ugyanezt a hatást érheted el az "\n\n+" kifejezés használatával. Ez a reguláris kifejezés illeszkedik a rekord utáni új sorra és a követő egy vagy több üres sorra. Ráadásul a reguláris kifejezések a lehető leghosszabb mintára illeszkednek (see section Mennyi szöveg illeszkedik?), így a következő rekord csak az üres sorok után kezdődik - nem számít, hogy hány üres sor van a két rekord között, mindig egy elválasztóként lesznek kezelve.

Van egy fontos különbség a `RS = ""' és a `RS = "\n\n+"' kifejezések között. Az első esetben az adat file-ban előforduló kezdő és záró üres sorokat nem veszi figyelembe, egyszerűen eldobja azokat. A második esetben ez nem történik meg. (s.s.)

Most, hogy a bemenetet feldaraboltuk több sorból álló rekordokra, a második lépés a rekordokon belüli mezők megállapítása. Az egyik megoldás, hogy a sorokat hagyományos módon feldaraboljuk mezőkre, de amikor az RS értéke egy üres szöveg az új sor karakter mindig mezőelválasztóként viselkedik. Ez csak egy ráadás az FS-ben megadott elválasztóhoz.

Ugyanakkor ez probléma is lehet, ha az új sor karaktert nem akarod mezőelválasztóként használni. Mivel ezt a speciális beállítást kikapcsolni nem lehet, csak a split függvény használatával tudod megfelelően feldarabolni a rekordot (see section Szövegmanipuláló beépített függvények).

Egy másik megoldás a rekordok feldarabolására, hogy minden mezőt külön sorba teszünk: ekkor az FS-t a "\n" szövegre kell beállítani. (Ez az egyszerű reguláris kifejezés csak egy új sor karakterre illeszkedik.)

Egy praktikus példa az így elrendezett adatokra egy levelezési címeket tartalmazó lista, ahol minden bejegyzést egy üres sor választ el. Egy ilyen file, `addresses', így nézhet ki:

Jane Doe
123 Main Street
Anywhere, SE 12345-6789

John Smith
456 Tree-lined Avenue
Smallville, MW 98765-4321

...

Egy egyszerű program a file feldolgozására:

# addrs.awk --- simple mailing list program

# Records are separated by blank lines.
# Each line is one field.
BEGIN { RS = "" ; FS = "\n" }

{
      print "Name is:", $1
      print "Address is:", $2
      print "City and State are:", $3
      print ""
}

A programot futtatva ezt az eredményt kapjuk:

$ awk -f addrs.awk addresses
-| Name is: Jane Doe
-| Address is: 123 Main Street
-| City and State are: Anywhere, SE 12345-6789
-| 
-| Name is: John Smith
-| Address is: 456 Tree-lined Avenue
-| City and State are: Smallville, MW 98765-4321
-| 
...

Egy másik programot is bemutatunk a címlisták feldolgozására egy későbbi fejezetben, see section Printing Mailing Labels.

Az alábbi táblázat összefoglalja, hogy a rekordok hogyan lesznek feldarabolva az RS értékétől függően (a `==' egyenlőséget jelent):

RS == "\n"
A rekordokat az új sor karakter választja el. Tehát minden sor egy rekord, az üres sorok is. Ez az alapbeállítás.
RS == egy bármilyen karakter
A rekordokat a megadott karakter választja el. Egymás után előforduló karakterek egy üres rekordot jelölnek.
RS == ""
A rekordokat egy vagy több üres sor választja el. Az új sor karakter mindig mezőelválasztóként viselkedik, az FS-től függetlenül. Kezdő és záró üres sorokat a file-ban nem veszi figyelembe.
RS == regexp
A rekordokat a reguláris kifejezésre illeszkedő szövegek választják el. A bemenet elején vagy végén illeszkedés a reguláris kifejezésre egy üres rekordot generál.

A gawk mindig beállítja az RT változót az RS-re illeszkedő szövegre.

Explicit beolvasás getline-al

Eddig a bemenetet az awk program számára vagy a szabványos bemenetről (általában a terminálról, néha egy másik program kimenetéből) vagy a parancssorban megadott file-okból olvastuk be. Az awk nyelvben a getline beépített függvénnyel lehet explicit módon a bemenet olvasását irányítani.

A getline bemutatása

A getline függvény hasznos lehet sokféleképpen, de kezdő felhasználóknak nem ajánlott. Azért itt tárgyaljuk, mivel minden a bemenettel kapcsolatos dolgot ebben a fejezetben tárgyalunk. A getline függvény bemutatására használt példákban előfordul olyan programozási megoldás, amit eddig még nem tárgyaltunk, így ezt a részt ajánlott újra elolvasni miután végigolvastad, és már jól ismered a könyvet.

A getline visszatérési értéke egy, ha sikeresen beolvasott egy rekordot és zérus ha elérte a bemenet végét. Ha valami hiba volt az olvasás során, például a file nem érhető el, akkor a visszatérési értéke -1. Ebben az esetben a gawk az ERRNO változót beállítja egy, a hibát leíró szövegre.

Az alábbi példákban a command egy shell parancsot helyettesít.

A getline használata argumentum nélkül

Az argumentum nélkül meghívott getline függvény az aktuális file-ból olvas be rekordot. Csak annyit csinál, hogy beolvassa a következő rekordot és feldarabolja mezőkre. Ez a viselkedés akkor lehet hasznos, ha befejezted az aktuális rekord feldolgozását és közvetlenül utána valamilyen speciális műveletet akarsz a következő rekordon elvégezni. Itt egy példa:

awk '{
     if ((t = index($0, "/*")) != 0) {
          # value will be "" if t is 1
          tmp = substr($0, 1, t - 1)
          u = index(substr($0, t + 2), "*/")
          while (u == 0) {
               if (getline <= 0) {
                    m = "unexpected EOF or error"
                    m = (m ": " ERRNO)
                    print m > "/dev/stderr"
                    exit
               }
               t = -1
               u = index($0, "*/")
          }
          # substr expression will be "" if */
          # occurred at end of line
          $0 = tmp substr($0, t + u + 3)
     }
     print $0
}'

Ez az program kitöröl minden a C programozási nyelvben szokásos megjegyzést, `/* ... */', a bemenetből. Ha a `print $0' kifejezést lecseréled valamilyen másik kifejezésre, akkor bonyolultabb műveletet is végezhetsz a megjegyzésektől mentes bemeneten, pl. reguláris kifejezésekkel változókat, stb. kereshetsz. A programnak van egy apró hibája -- ugyanis nem működik, ha egy megjegyzés az adott sorban végződik és egy másik megjegyzés ugyanabban a sorban kezdődik.

Ha a getline függvényt így használod, akkor frissíti az NF (mezők száma; see section Mezők elérése), az NR (az eddig beolvasott rekordok száma; see section Hogyan történik a feldarabolás rekordokra), az FNR (az ebből a file-ból beolvasott rekordok száma) és a $0 változó értékét.

Megjegyzés: A getline az új $0 értéket használja bármilyen további szabályban megadott mintaillesztésre. A $0 azon értéke, ami az aktuális szabályt aktiválta elveszett (s.s.). Ezzel ellentétben a next kifejezés beolvassa a következő rekordot és a feldolgozást az első szabálytól kezdi. See section A next kifejezés.

Beolvasás egy változóba getline-al

A `getline var' kifejezés beolvassa a következő rekordot és a var változóban tárolja. Semmilyen más feldolgozás nem történik.

Például tegyük fel, hogy a következő sor a bemeneten egy megjegyzés vagy egy speciális szöveg és be akarod olvasni és tárolni, de egy szabályt sem akarsz aktiválni. A getline ezen formája ezt teszi lehetővé, ráadásul az awk fő rekord-beolvasás-és-minden-szabály-ellenőrzése ciklus az így beolvasott rekordot soha nem látja.

Az alábbi példa a bemenet minden második sorát felcseréli az előzővel, tehát ha a bemenet:

wan
tew
free
phore

akkor az eredmény:

tew
wan
phore
free

A program:

awk '{
     if ((getline tmp) > 0) {
          print tmp
          print $0
     } else
          print $0
}'

Ha a getline függvényt így használod, akkor csak az NR és az FNR (és természetesen a var) változók értéke változik meg. A beolvasott rekordot nem darabolja fel mezőkre, így sem a a mezők sem a $0 és az NF értéke nem változik meg.

Beolvasás file-ból getline-al

A `getline < file' kifejezés beolvassa a következő rekordot a file-ból. Itt a file egy szöveg értékű kifejezés kell legyen, ami a file nevét adja meg. A `< file' kifejezést átirányításnak is szokták nevezni, mivel azt adja meg, hogy a bemenet valahonnan máshonnan (más irányból) jöjjön.

Például az alábbi program egy új rekordot olvas be a `secondary.input' file-ból, ha az első mező értéke tíz az aktuális rekordban.

awk '{
    if ($1 == 10) {
         getline < "secondary.input"
         print
    } else
         print
}'

Mivel nem a fő bemenetet használja, az NR és az FNR változók értéke nem változik meg, de az újonnan beolvasott rekordot feldarabolja mezőkre a normális módon, így a $0 és az NF is megváltozik.

A POSIX szabvány szerint a `getline < expression' nem egyértelmű, ha a kifejezés tartalmaz a `$'-on kívül egyéb operátort; például a `getline < dir "/" file' nem egyértelmű, mert az összefűzés operátor nincs zárójelek között. Ha több awk implementációval is használni szeretnéd a programodat, akkor a `getline < (dir "/" file)' kifejezést érdemes használni.

Beolvasás file-ból egy változóba a getline-al

A `getline var < file' kifejezés beolvassa a következő rekordot a file-ból és a var változóban tárolja. Mint előbb, a file itt is egy szöveg értékű kifejezés kell legyen, ami a file nevét adja meg.

Ebben az esetben egyetlen beépített változó tartalma sem változik meg és a rekord nem lesz feldarabolva mezőkre. Egyedül a var változó kap új értéket.

Például az alábbi program a bemeneti file minden sorát kinyomtatja, kivéve azokat a rekordokat amelyek a `@include filename' kifejezést tartalmazzák. Ezeket a rekordokat a filename file tartalmával helyettesíti.

awk '{
     if (NF == 2 && $1 == "@include") {
          while ((getline line < $2) > 0)
               print line
          close($2)
     } else
          print
}'

Érdemes megfigyelni, hogy az extra file neve nincs beépítve a programba, hanem a második mezőből olvassuk ki.

A close függvény biztosítja, hogy ha két azonos `@include' sor van a file-ban, akkor a megadott file tartalma kétszer lesz kinyomtatva. See section Bemeneti és kimeneti file-ok és csövek lezárása..

A program egyik hibája, hogy beágyazott `@include' kifejezéseket nem tud feldolgozni (egy `@include' egy másik `@include' kifejezéssel megadott file-ban), mint ahogy egy igazi macro feldolgozó programnak kellene. See section An Easy Way to Use Library Functions, amely tartalmaz egy megoldást beágyazott `@include' kifejezésekre.

Beolvasás csőből (pipe) getline-al

Egy másik program kimenetét átirányíthatod a getline-ba, a `command | getline' kifejezéssel. Ebben az esetben a command mint egy shell parancs fog lefutni, és a kimenetét az awk fogja használni, mint bemenetet. A getline egyszerre csak egy rekordot olvas be a csőből.

Például az alábbi program a bemenetét a kimenetre másolja, kivéve azokat a sorokat amelyek egy `@execute' szöveget tartalmaznak, amikor is a rekord többi részét mint shell parancs hajtja végre és az eredményt nyomtatja ki.

awk '{
     if ($1 == "@execute") {
          tmp = substr($0, 10)
          while ((tmp | getline) > 0)
               print
          close(tmp)
     } else
          print
}'

A close függvény biztosítja, hogy ha két azonos `@include' sor van a file-ban, akkor a megadott file tartalma kétszer lesz kinyomtatva. See section Bemeneti és kimeneti file-ok és csövek lezárása..

Tehát, ha ez a bemenet:

foo
bar
baz
@execute who
bletch

a program ezt az eredményt produkálja:

foo
bar
baz
arnold     ttyv0   Jul 13 14:22
miriam     ttyp0   Jul 13 14:23     (murphy:0)
bill       ttyp1   Jul 13 14:23     (murphy:0)
bletch

A program végrehajtotta a who parancsot és annak eredményét nyomtatja ki. (Ha kipróbálod a programot, valószínű, hogy más eredményt fogsz kapni, mivel azokat a felhasználókat fogja kinyomtatni akik be vannak jelentkezve a rendszeren.)

A getline ilyen használata esetén a bemenetet feldarabolja, beállítja az NF értékét és a $0-t újraértékeli. Az NR és az FNR értéke nem változik meg.

A POSIX szabvány szerint a `expression | getline' nem egyértelmű, ha a kifejezés tartalmaz a `$'-on kívúl egyéb operátort; például a `"echo " "date" | getline' nem egyértelmű, mert az összefűzés operátor nincs zárójelek között. Ha több awk implementációval is használni szeretnéd a programodat, akkor a `("echo " "date") | getline' kifejezést érdemes használni. (A gawk helyesen kezeli ezt az esetet, de nem érdemes ebben bízni. A zárójelekkel egyébként is jobban olvasható, hogy mi is történik.)

Beolvasás csőből (pipe) egy változóba getline-al

Ha a `command | getline var' kifejezést használod, akkor a command kimenete a getline-ba lesz átirányítva majd a var változót is beállítja. Például az alábbi program beolvassa a mai dátumot és a pontos időt a current_time változóba a date segédprogram segítségével, majd kinyomtatja:

awk 'BEGIN {
     "date" | getline current_time
     close("date")
     print "Report printed on " current_time
}'

Ebben az esetben egyetlen beépített változó sem változik meg és a rekordot sem darabolja fel mezőkre.

Összefoglaló a getline változatairól

A getline használata esetén bár a $0 és az NF értéke lehet hogy megváltozik, de a beolvasott rekordot nem teszteli minden mintával az awk programban, ami normális esetben történne. Ugyanakkor a beolvasást követő szabályokban az új rekordot használja.

Sok awk implementáció egyre korlátozza az egyszerre megnyitható csövek számát. A gawk-ban nincs ilyen korlátozás, annyi csövet nyithatsz meg, amennyit az operációs rendszer megenged.

A getline-nak egy érdekes mellékhatása van, ha a BEGIN szabályon belül használjuk. Mivel az átirányítás nélküli getline a parancssorban megadott file-okból olvas, az első getline kifejezés beállítja a FILENAME változót is. Általában a FILENAME-nek nincs értéke a BEGIN szabályon belül, mivel a file-ok feldolgozása még nem kezdődött meg (s.s.). (See section A BEGIN és az END speciális minták, és see section Információt hordozó beépített változók.)

Az alábbi táblázat összefoglalja a getline hat lehetséges használati módját, illetve megadja, hogy mely változók értéke változik meg.

getline
beállítja a $0, NF, FNR és az NR változókat.
getline var
beállítja a var, FNR és az NR változókat.
getline < file
beállítja a $0 és az NF változókat.
getline var < file
beállítja a var változót.
command | getline
beállítja a $0 és az NF változókat.
command | getline var
beállítja a var változót.


Go to the first, previous, next, last section, table of contents.