Az egyik leggyakoribb tevékenység a nyomtatás, vagyis a teljes bemenet
vagy csak a bemenet egy részének a kinyomtatása. Egyszerű nyomtatás
esetén a print
-et érdemes használni. Bonyolultabb formázásra és
nyomtatásra a printf
alkalmas. Mindkét lehetôséget ebben a fejezetben
tárgyaljuk.
print
kifejezés
A print
kifejezés egyszerű, szabványos formázással nyomtatja ki
az eredményt, csak meg kell adni a szövegeket, számokat egy
vesszôvel elválasztott listában. A nyomtatás során szóközök választják
el a megadott lista elemeit, majd az egészet egy új sor karakter zárja.
Egy kifejezés valahogy így néz ki:
print elem1, elem2, ...
Ha akarod, akkor a teljes listát zárójelek közé teheted. A zárójel kötelezô,
ha a lista bármely eleme használja a `>' karaktert (összehasonlító
operátor), mivel összekeverhetô az átirányítás operátorral
(see section A print
és a printf
kimenetének átirányítása).
A kinyomtatandó elemek lehetnek szöveg vagy szám konstansok, az aktuális
rekord mezôi (mint a $1
), változók vagy bármilyen awk
kifejezés. A numerikus kifejezéseket elôbb szöveggé konvertálja, és csak
utána nyomtatja ki.
A print
kifejezésnek teljesen szabadon megadhatod, hogy mit
nyomtasson ki, de két kivételtôl eltekintve nem tudod befolyásolni,
hogy hogyan jelenítse meg az eredményt -- hány számjegyet,
exponenciális vagy lebegôpontos formát használjon és így tovább.
(A kivételeket két bekezdésben mutatjuk be,
see section Kimeneti elválasztó és
a section A numerikus adatok formátumának megadása a print
esetén.)
A megjelenítési forma megadásához a printf
kifejezést kell
használni
(see section Nyomtatás a printf
kifejezéssel).
Az önmagában álló `print' kifejezés megegyezik a `print $0'
kifejezéssel: kinyomtatja a teljes rekordot. Egy üres sor nyomtatásához
a `print ""' kifejezést kell használni, ahol a ""
egy üres szöveg.
Egy adott szöveget szöveg konstansként érdemes kinyomtatni. Ha elfelejted
megadni a macskakörmöket, akkor a szavak mint awk
kifejezések lesznek
kezelve, és a program valószínűleg hibát fog jelezni. Emlékezz arra is, hogy
minden elem közé egy extra szóközt is nyomtat.
Minden print
kifejezés legalább egy sort nyomtat, persze
lehet hogy többet is. Ha egy szöveg tartalmazza az új sor karaktert,
akkor azt is kinyomtatja, vagyis a szöveg többi részét egy új sorba
nyomtatja ki. Egy print
kifejezés tetszôleges számú sort
nyomtathat ki.
print
kifejezésselAz elsô példa bemutatja a beágyazott új sor karakterek nyomtatását (a `\n' escape szekvencia az új sor karaktert reprezentálja; see section Escape szekvenciák):
$ awk 'BEGIN { print "line one\nline two\nline three" }' -| line one -| line two -| line three
A második példa minden bemeneti rekordból kinyomtatja az elsô két mezôt egy szóközzel elválasztva:
$ awk '{ print $1, $2 }' inventory-shipped -| Jan 13 -| Feb 15 -| Mar 15 ...
Gyakori hiba a print
használata során, hogy nem teszünk vesszôt
az elemek közé. Ennek az a hatása, hogy közvetlenül egymás után írja ki
az elemeket, mivel ez az írásmód az awk
-ban az összefűzést jelenti.
Tehát ugyanaz a példa vesszôk nélkül:
$ awk '{ print $1 $2 }' inventory-shipped -| Jan13 -| Feb15 -| Mar15 ...
Ha valaki nem ismeri az `inventory-shipped' file tartalmát, akkor
a fenti példák eredményei nem mondanak túl sokat. Ilyenkor jól jöhet
egy fejléc, jelezve, hogy az elsô mezô a hónap ($1
) a második mezô
($2
) pedig a zöld rekeszek száma. A fejlécet a BEGIN
mintán belül nyomtatjuk ki, hogy csak egyszer jelenjen meg
(see section A BEGIN
és az END
speciális minták):
awk 'BEGIN { print "Hónap Rekesz" print "----- ------" } { print $1, $2 }' inventory-shipped
Kitalálod, hogy mi fog történni? A program futtatása után ezt kapjuk:
Month Crates ----- ------ Jan 13 Feb 15 Mar 15 ...
Az adatok és a fejléc nem kerül egy oszlopba! A probléma persze megoldható ha megfelelô számú szóközt teszünk a mezôk közé:
awk 'BEGIN { print "Hónap Rekesz" print "----- ------" } { print $1, " ", $2 }' inventory-shipped
Könnyű elképzelni, hogy több oszlop igazítása ezzel a módszerrel elég
bonyolult lehet. Kettô vagy három oszlop esetén a szóközök még könnyen
kiszámolhatók, de több oszlop esetén könnyű eltéveszteni. Ezért találták
ki a printf
kifejezést
(see section Nyomtatás a printf
kifejezéssel),
aminek az egyik specialitása az oszlopok igazítása.
Mellékesen, egy print
vagy printf
kifejezés folytatható a
következô sorban, ha a vesszô után egy új sor karakter áll
(see section awk
kifejezések és sorok).
Ahogy azt korábban leírtuk, a print
kifejezés argumentumait
vesszô választja el. Ennek hatására a kinyomtatás során az elemek között egy
szóközt nyomtat. Ennek persze nem kell így lennie; a szóköz csak az
alapbeállítás. Bármilyen karaktersorozat megadható, mint kimeneti
mezôelválasztó, az OFS
beépített változónak. A változó
kezdeti értéke a " "
szöveg, egy szóköz.
Egy teljes print
kifejezés kimenete egy kimeneti rekord.
Minden print
kifejezés kinyomtat egy kimeneti rekordot, majd
egy szöveget amit úgy hívnak, hogy kimeneti rekordelválasztó, az
ORS
beépített változóban megadott értéket. Az ORS
kezdeti értéke a "\n"
, az új sor karakter; így alapesetben
minden print
kifejezés egy új sorral zárja a rekordot.
Természetesen megváltoztathatod, hogy a kimeneti rekordok és mezôk hogyan
legyenek elválasztva, ha új értéket adsz az OFS
és/vagy ORS
változóknak. Ezt általában a BEGIN
szabályban érdemes megtenni,
(see section A BEGIN
és az END
speciális minták),
a bemenet feldolgozásának megkezdése elôtt. A változókat beállíthatod
a parancssorból is a bemeneti file-ok elôtt vagy a `-v' parancssori
opció használatával (see section Command Line Options).
Az alábbi példa kinyomtatja az elsô és a második mezôt egy pontos vesszôvel elválasztva és a rekordok közé egy új, üres sort illesztve:
$ awk 'BEGIN { OFS = ";"; ORS = "\n\n" } > { print $1, $2 }' BBS-list -| aardvark;555-5553 -| -| alpo-net;555-3412 -| -| barfly;555-7685 ...
Ha az ORS
nem tartalmaz egy új sor karaktert, akkor minden kimenet
egy sorba lesz kinyomtatva, kivéve persze ha valami más explicit módon
nincs megadva az új sor karakter nyomtatása.
print
esetén
Amikor a print
kifejezéssel egy számot nyomtatunk ki, az
awk
átalakítja a számot szöveggé, majd ezt a szöveget nyomtatja
ki. Az awk
az sprintf
függvényt használja a
konvertáláshoz
(see section Szövegmanipuláló beépített függvények).
Egyelôre elég annyit elmondani, hogy az sprintf
úgynevezett
formátumleírót használ, ami megadja, hogy a szám (vagy szöveg)
hogyan fog megjelenni. A különbözô formátumokat részletesen tárgyaljuk
egy késôbbi alfejezetben, section Formátumleíró betűk.
Az OFMT
beépített változó tartalmazza az alap formátumleírót,
amit a print
használ a számok szöveggé konvertálása során. Az
OFMT
alapértéke "%.6g"
. Ha más értéket adunk meg
az OFMT
-nek, akkor szabályozható, hogy a számokat hogyan
nyomtassa ki a print
. Egy rövid példa:
$ awk 'BEGIN { > OFMT = "%.0f" # minden számot integerként nyomtat ki > print 17.23 }' -| 17
A POSIX szabvány szerint az awk
viselkedése nem definiált, ha az
OFMT
nem lebegôpontos formátumleírót tartalmaz (s.s.).
printf
kifejezéssel
Ha a print
lehetôségeinél jobban akarod kontrollálni a
nyomtatási formátumot, akkor a printf
kifejezést használd.
A printf
-el megadhatod a nyomtatási szélességet minden elemre
és a számokat különbözô formátumban (különözô számrendszerben,
exponenciális vagy lebegôpontos alakban, megadott számjegy pontossággal)
nyomtathatod ki. Mindezt egy formátumszöveg megadásával érheted el.
printf
bemutatása
A printf
kifejezést így kell használni:
printf formátum, elem1, elem2, ...
Az argumentumokat zárójelek közé is teheted. A zárójel kötelezô, ha
bármelyik elem a `>' összehasonlító operátort tartalmazza, mert
az awk
összekeverheti az átirányítás operátorral
(see section A print
és a printf
kimenetének átirányítása).
A printf
és a print
közötti különbség a format
argumentum. Ez egy szöveg értékű kifejezés; megadja, hogy a többi
argumentumot hogyan nyomtassa ki. A kifejezést formátumszövegnek
hívják.
A formátumszöveg nagyon hasonló az ANSI C-ben használt printf
függvény argumentumához. A format kifejezés jelentôs része
egyszerű szöveg, amit csak ki kell nyomtatni. A szöveg között vannak
elszórva a formátumleírók. Minden elemhez tartozik egy. A formátum
szöveg veszi a következô argumentumot, és az adott helyen kinyomtatja.
A printf
kifejezés nem kezd új sort a nyomtatás végén automatikusan.
Csak annyit és azt nyomtat ki, amit a formátumszöveg megad, így ha egy
új sor karakter is kell a szöveg végére, akkor azt explicit módon kell
megadni. Az OFS
és az ORS
változóknak nincs hatása a
printf
kifejezésre, így:
BEGIN { ORS = "\nOUCH!\n"; OFS = "!" msg = "Don't Panic!"; printf "%s\n", msg }
A program még mindig csak annyit nyomtat ki, hogy `Don't Panic!'.
Egy formátumleíró a `%' karakterrel kezdôdik és egy betűvel végzôdik. (Ha csak a `%' karaktert akarod kinyomtatni, akkor a `%%' karaktersorozatot kell használni.) A formátumleíró betű határozza meg a kinyomtatandó adat típusát. A leíró többi része csak módosítja a megjelenést, mint például a nyomtatási szélességet.
Itt egy lista a formátumleíró betűkrôl:
c
d
i
e
E
printf "%4.3e\n", 1950`1.950e+03' -t fog kinyomtatni, négy értékes jegyre, amibôl három számjegy a tizedes pont után áll. A `4.3' egy leíró módosító és késôbb tárgyaljuk. A `%E' egy nagy `E' betűt használ a számban a kis `e' betű helyett.
f
printf "%4.3f", 1950`1950.000' -t jeleníti meg négy értékes jegyre, amibôl három számjegy a tizedes pont után áll. A `4.3' egy leíró módosító és késôbb tárgyaljuk.
g
G
o
s
x
X
%
printf
argumentumait, és minden
leíró módosítót figyelmen kívül hagy.
Amikor az egész (integer) formátumleíró betűt használjuk
egy olyan értéknél, ami
nem reprezentálható a C long
típussal, akkor a gawk
automatikusan a `%g' formázási módba kapcsol. Más awk
verziók valótlan értéket nyomtathatnak, vagy valami furcsa dolgot
csinálhatnak ebben az esetben (s.s.).
printf
formátum módosítóiA formátum leírók módosító komponenseket is tartalmazhatnak, amelyek meghatározzák, hogy az elembôl mennyi jelenik meg. A módosító komponenseket a `%' karakter és a formátumleíró betű között kell elhelyezni. Az alábbi példákban a "*" jelet használjuk a szóközök helyén a kimenetben. A módosítók az alábbi felsorolás sorrendjében jelenhetnek meg:
-
printf "%-4s", "foo"ezt adja eredményül: `foo*'.
szóköz
+
#
0
szélesség
printf "%4s", "foo"eredménye: `*foo'. A szélesség a minimumot adja meg és nem a maximumot. Így ha a kinyomtatandó elem szélesebb mint a megadott érték ettôl függetlenül az egész elemet kinyomtatja, például:
printf "%4s", "foobar"eredménye: `foobar'. A szélesség elôtti mínusz jel hatására az extra szóközöket a jobb oldalra rakja.
.pontosság
printf "%.4s", "foobar"eredménye: `foob'.
A C programozási nyelv printf
kifejezésében használható
dinamikus szélesség és pontosság meghatározás ("%*.*s"
)
az awk
-ban is engedélyezett. Ebben az esetben nem a formátum
szövegben kell megadni a szélesség és/vagy pontosság
értékét, hanem mint argumentum kell átadni a kifejezésnek, például:
w = 5 p = 3 s = "abcdefg" printf "%*.*s\n", w, p, s
pontosan ugyanaz, mint
s = "abcdefg" printf "%5.3s\n", s
Mindkét program a `**abc' kifejezést nyomtatja ki.
Az awk
korábbi verziói nem támogatták ezt a lehetôséget. Ha ilyen
awk
-ot kell használnod, akkor az összefűzés operátorral szimulálhatod
a dinamikus módot:
w = 5 p = 3 s = "abcdefg" printf "%" w "." p "s\n", s
Bár nem egyszerű olvasni ezt a formát, de működik.
A C programozók már hozzászokhattak a `l' és `h' megadásához
a printf
formátumszövegében, de az awk
-ben ezek
nem használhatók. A legtöbb awk
implementáció csendben
figyelmen kívül hagyja ezeket a módosítókat. Ha a `--lint' opció
meg van adva a parancssorban (see section Command Line Options),
akkor a gawk
figyelmeztet ezen módosítók használata esetén.
Ha a `--posix' opció van megadva, akkor használatuk végzetes
hiba, a program azonnal leáll.
printf
példák
Ez a példa egy igazított táblázatot nyomtat ki a printf
segítségével:
awk '{ printf "%-10s %s\n", $1, $2 }' BBS-list
kinyomtatja a `BBS-list' file-ban található rendszerek nevét ($1
)
egy tíz karakter szélességű mezôbe, balra igazítva. Ezenkívül kinyomtatja
a telefonszámot ($2
) is. Az alábbi két oszlopból álló táblázat az
eredmény:
$ awk '{ printf "%-10s %s\n", $1, $2 }' BBS-list -| aardvark 555-5553 -| alpo-net 555-3412 -| barfly 555-7685 -| bites 555-1675 -| camelot 555-0542 -| core 555-2912 -| fooey 555-1234 -| foot 555-6699 -| macfoo 555-6480 -| sdace 555-3430 -| sabafoo 555-2127
Észrevetted, hogy a telefonszámot nem mint számot nyomtattuk ki? A telefonszámokat mint szöveg kellett kinyomtatni, mivel szerepel egy mínusz jel a számban. Ha mint számot nyomtatjuk ki, akkor csak az elsô három számjegyet kapnánk meg eredményül, `555'.
A telefonszám formátumánál nem adtunk meg szélességet, mivel az utolsó elem a sorban, így nem akarunk szóközöket utána.
A táblázatot szebbé tehetjük, ha egy fejlécet adunk az oszlopok tetejéhez.
Ehhez a BEGIN
mintát kell alkalmazni
(see section A BEGIN
és az END
speciális minták),
mivel így csak egyszer, az awk
program legelején nyomtatja ki a
fejlécet:
awk 'BEGIN { print "Név Szám" print "--- ----" } { printf "%-10s %s\n", $1, $2 }' BBS-list
Észrevetted, hogy a print
és printf
kifejezéseket is használtunk
a fenti példában? Használhatunk csak printf
kifejezést is:
awk 'BEGIN { printf "%-10s %s\n", "Név", "Szám" printf "%-10s %s\n", "---", "----" } { printf "%-10s %s\n", $1, $2 }' BBS-list
Mivel ugyanazt a formátumot használtuk a fejléc és az adatok nyomtatására, így biztosak lehetünk benne, hogy megfelelôen lesznek igazítva.
Ha hangsúlyozni akarjuk, hogy ugyanazt a formátumot kell használni mindegyik esetben, akkor a formátumot egy változóban is tárolhatjuk:
awk 'BEGIN { format = "%-10s %s\n" printf format, "Név", "Szám" printf format, "---", "----" } { printf format, $1, $2 }' BBS-list
Most már tudod, hogyan kellett volna használni a printf
kifejezést
az `inventory-shipped' file-ból nyert táblázat nyomtatásánál
(see section A print
kifejezés). Meg tudod csinálni?
print
és a printf
kimenetének átirányítása
Eddig csak azokkal az esetekkel foglalkoztunk, amikor a nyomtatás a
szabványos kimeneten, általában a terminálon jelent meg. A print
és a printf
is képes a kimenetet átirányítani.
Az átirányítást a print
vagy a printf
kifejezés után
kell írni és a formája ugyanolyan, mint a shell-ben használt átirányítás.
Az átirányításnak három formája van: kimenet egy file-ba, kimenet
hozzáfűzése egy file-hoz és kimenet átirányítása egy csôvön (pipe-on)
keresztül egy másik parancsba. A print
kifejezéssel mutatjuk be
az átirányítás használatát, de ugyanígy minden érvényes a printf
kifejezésre is.
print elemek > output-file
awk
program a BBS neveket a `name-list'
file-ba írja, míg a telefonszámokat a `phone-list' file-ba. Minden
név vagy szám egy külön sorba kerül.
$ awk '{ print $2 > "phone-list" > print $1 > "name-list" }' BBS-list $ cat phone-list -| 555-5553 -| 555-3412 ... $ cat name-list -| aardvark -| alpo-net ...
print elemek >> output-file
awk
létrehozza.
print elemek | parancs
awk
megnyitja a csövet
a parancs felé, majd az elemeket kiírja a csôbe.
A parancs átirányítási argumentum egy awk
kifejezés. Az értékét
egy szöveggé alakítja, ami megadja a végrehajtandó shell parancsot.
Az alábbi példa két file-t hoz létre, a BBS nevek egy rendezetlen és egy
ábécé sorrendben visszafelé rendezett listáját:
awk '{ print $1 > "names.unsorted" command = "sort -r > names.sorted" print $1 | command }' BBS-listA rendezetlen listát egy normál átirányítással írjuk ki, míg a rendezést a
sort
segédprogram végzi el, ami egy csövön keresztül kapja az
adatokat.
A következô példa átirányítással küld egy üzenet a `bug-system'
levelezési listára. Ilyen program hasznos lehet ha a rendszer adminisztrációra
használt awk
program hibát talál valahol.
report = "mail bug-system" print "Awk script failed:", $0 | report m = ("at record number " FNR " of " FILENAME) print m | report close(report)Az üzenetet összefűzéssel készíti el, és az
m
változóban tárolja, majd
egy csövön keresztül a mail
programnak küldi tovább.
A close
függvény alkalmazása fontos, mivel ez lezárja a kimeneti
csövet.
See section Bemeneti és kimeneti file-ok és csövek lezárása..
A példa azt is bemutatja, hogy hogyan használhatunk egy változót a file
vagy a parancs reprezentálására. A változók azért is hasznosak, mert
egyébként minden alkalommal pontosan ugyanúgy kellene leírni a hosszú
szövegeket.
A `>', `>>' vagy `|' átirányítás arra kéri a rendszert, hogy nyisson meg egy file-t vagy csövet, de csak akkor, ha az adott file-t vagy parancsot még nem használta a program vagy ha az utolsó használat végén le lett zárva.
Mint ahogy azt már korábban írtuk
(see section Összefoglaló a getline
változatairól),
néhány awk
implementáció csak egy csô (pipe) megnyitását engedélyezi.
A gawk
-ban nincs ilyen korlátozás, annyi csövet lehet megnyitni,
amennyit az operációs rendszer engedélyez.
gawk
-banHagyományosan egy program összesen három karakterfolyamot (stream-et) használ beolvasásra és kiírásra. Ezek a szabványos bemenet, szabványos kimenet és a szabványos hibakimenet, amelyek általában a terminálodhoz kapcsolódnak, de gyakran a shell átirányítja ôket a `<', `<<', `>', `>>', `>&' és a `|' operátorok valamelyikével. A szabványos hibakimenet a hibaüzeneteket jeleníti meg; azért van két különbözô karakterfolyam, a szabványos kimenet és a szabványos hibakimenet, mert így külön-külön lehet ôket átirányítani.
Néhány awk
implementáció esetén az egyetlen lehetôség egy awk
programban a hibaüzenetek megjelenítésére a szabványos hibakimeneten
keresztül az alábbi módszer:
print "Serious error detected!" | "cat 1>&2"
Ez úgy működik, hogy egy csövet nyit meg egy olyan shell parancs felé,
amelyik el tudja érni a szabványos hibakimenetet. A szabványos hibakimenet
értékét az awk
-tól veszi át. Ez a megoldás nem elegáns és
nem is hatékony, mivel egy másik programot kell indítani. Így az emberek
jelentôs része nem ezt a módszert használja, helyette a hibaüzeneteket a
terminálra küldi, például így:
print "Serious error detected!" > "/dev/tty"
Általában ennek ugyanaz a hatása, de nem mindig: habár a terminál a
szabványos hibakimenet az esetek nagy részében, de át lehet irányítani,
és ebben az esetben a terminálra írás nem jó megoldás. Ráadásul ha az
awk
a háttérben fut, akkor nincs is terminál hozzárendelve, és a
`/dev/tty' megnyitása nem lesz sikeres.
A gawk
speciális file neveket biztosít a három alap karakterfolyam
eléréséhez. Ha a kimenetet vagy a bemenetet átirányítjuk, és a file neve
megegyezik valamelyik speciális névvel, akkor a gawk
az adott
karakterfolyamot fogja használni.
awk
-ot elindító programnak kell megnyitnia (általában a shell).
Ha csak nem bravúroskodsz, akkor csak a 0, 1 és a 2 file leírók
állnak rendelkezésre.
A `/dev/stdin', `/dev/stdout' és `/dev/stderr' file-ok megegyeznek a `/dev/fd/0', `/dev/fd/1' és `/dev/fd/2' file-okkal sorrendben, de a nevük kifejezôbb.
A helyes módszer egy hiba megjelenítésére egy gawk
programból
a `/dev/stderr' használatával:
print "Serious error detected!" > "/dev/stderr"
A gawk
olyan speciális file-ok elérését is biztosítja, amelyek
az éppen futó gawk
-ról adnak információt. Minden ilyen "file"
csak egy rekordnyi információt tartalmaz. Ha többször akarod kiolvasni
az értékét, akkor elôbb le kell zárni a close
függvénnyel
(see section Bemeneti és kimeneti file-ok és csövek lezárása.).
A file-ok:
$1
getuid
rendszer függvény visszatérési értéke (a valódi felhasználói
azonosító, ID).
$2
geteuid
rendszer függvény visszatérési értéke (az effektív felhasználói
azonosító).
$3
getgid
rendszer függvény visszatérési értéke (a felhasználó valódi
csoport azonosítója).
$4
getegid
rendszer függvény visszatérési értéke (a felhasználó effektív
csoport azonosítója).
getgroups
rendszer függvény által visszaadott
csoport azonosítókat tartalmazza. (Nem minden rendszer támogatja, hogy egy
felhasználó több csoportba tartozhat.)
Ezeket a speciális file-okat a parancssorban is lehet használni mint adat
file-ok vagy az awk
programon belül átirányítással, de nem
használhatók mint program file a `-f' opcióval.
"Compatibility" módban (see section Command Line Options)
a gawk
nem ismeri fel ezeket a speciális file-okat.
Figyelem: Ha a rendszereden nincs `/dev/fd' könyvtár
(vagy bármely más fent megadott speciális file), akkor a gawk
maga
fogja értelmezni a megadott file nevet. Például a `/dev/fd/4'
mint kimenet használata esetén a program a 4-es file leíró által megadott
file-ba fog írni és nem egy olyan file leíróba ami a 4-es file leíró
másolata. Általában ez nem annyira érdekes; de fontos, hogy ne
zárjuk le a 0, 1 és 2 -es file leírókat, ugyanis ebben az esetben
az awk
viselkedése megjósolhatatlan.
A futó awk
programról információt adó file-ok lehet,
hogy nem lesznek benne a gawk
késôbbi verzióiban,
see section Probable Future Extensions.
Ha többször ugyanazt a file nevet vagy shell parancsot használjuk a
getline
-al (see section Explicit beolvasás getline
-al)
egy awk
programon belül, a file-t csak az elsô alkalommal nyitja meg
(a parancsot csak az elsô alkalommal hajtja végre). Ezzel egy idôben
beolvassa az elsô rekordot. A következô alkalommal, amikor ugyanazt
a file-t vagy shell parancsot hasnáljuk a getline
-al, a következô
rekordot olvassa be.
Ugyanez érvényes a csövekre is ha írunk bele; az adott file-ra vagy
parancsra emlékszik az awk
és az elsô alkalom után mindig
ugyanabba a file-ba írja vagy ugyanannak a parancsnak küldi a kimenetet.
A file vagy csô addig marad nyitva, amíg az awk
ki nem lép.
Ez persze azt jelenti, hogy ha ugyanazt a file-t többször szeretnéd
beolvasni az elejétôl vagy ugyanazt a shell parancsot szeretnéd többször
lefuttatni, akkor extra lépéseket kell tenned. A close
függvényt
kell használni:
close(filenév)
vagy
close(parancs)
A filenév vagy parancs argumentum bármilyen kifejezés lehet, de az értéke pontosan ugyanaz kell legyen mint amit a megnyitásnál használtunk (a szóközök és egyéb "extra" karakterek is fontosak). Például ha egy csövet így nyitsz meg:
"sort -r names" | getline foo
akkor bezárni így kell:
close("sort -r names")
Miután ez a függvény lefutott a következô getline
, print
vagy printf
kifejezésnél ugyanazt a file-t újra megnyitja vagy
ugyanazt a parancsot újra lefuttatja.
Mivel a lezárásnál ugyanolyan értékű kifejezést kell használni mint a megnyitásnál ezért érdemes a file nevét vagy a parancsot egy változóban tárolni. Az elôbbi példa tehát így fog kinézni:
sortcom = "sort -r names" sortcom | getline foo ... close(sortcom)
Ez segít elkerülni a nehezen megtalálható "elgépelési" hibákat az
awk
programodban.
Az alábbiakban leírunk néhány indokot, hogy a kimenetet miért érdemes/kell lezárni:
awk
programból hozzuk létre a file-t, mint amibôl
késôbb visszaolvassuk. A létrehozás, írás után le kell zárni a file-t, így a
getline
függvénnyel elölrôl olvasható.
awk
programból több file-ba írunk. Ha nem zárjuk le
a file-okat, lehet, hogy egy idô után több file-t szeretnénk nyitva tartani
egyszerre, mint amennyit a rendszer engedélyez. Így ha egy file-al végeztünk,
zárjuk le.
mail
programba irányítottuk,
akkor az aktuális üzenetet addig nem küldi el, amíg a csövet le nem
zárjuk.
mail
programba. Ha több sort
is kiírunk, akkor azok ugyanabba az üzenetbe kerülnek. Ezzel ellentétben
ha a csövet lezárjuk minden sor után, akkor minden sor egy különálló
üzenet lesz.
A close
függvény zérust ad vissza, ha a lezárás sikeres volt, egyébként
valamilyen zérustól különbözô értéket. Ebben az esetben a gawk
beállítja az ERRNO
változót egy, a hibát leíró üzenetre.
Ha több file-t próbálsz megnyitni, mint amit a rendszer engedélyez, akkor a
gawk
megpróbálja a rendelkezésre álló nyitott file-okat megosztani
(multiplex), és az új file-t is megnyitni. Ez a lehetôség az operációs
rendszertôl is függ; nem mindig működik, ezért jó programozási szokás
és könnyíti a hordozhatóságot ha a file-t mindig lezárod, miután már
nem használod.
Go to the first, previous, next, last section, table of contents.