Go to the 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.