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


Beépített függvények

A beépített függvények olyan függvények, amelyek mindig az awk programod rendelkezésére állnak. Ez a fejezet definiálja az awk összes beépített függvényét; néhányat más bekezdésekben is megemlítettünk már. (Te is definiálhatsz függvényeket. See section Felhasználó által definiált függvények.)

Beépített függvények hívása

Ahhoz, hogy egy beépített függvényt meghívhassunk, a nevét kell leírni, majd az argumentumait zárójelek között. Például, `atan2(y + z, 1)' a atan2 függvényt fogja meghívni két argumentummal.

A függvénynév és a nyitó zárójel közötti szóközöket nem veszi figyelembe az awk, de azt tanácsoljuk, hogy ne használj szóközöket itt. A felhasználó által definiálható függvények hívásánál a szóközök nem megengedettek, és ha nem használsz szóköz karaktert a függvénynév és a nyitó zárójel között, akkor könnyebb ezt a hibát elkerülni.

Minden beépített függvény elfogad egy adott számú argumentumot. Bizonyos esetekben, az argumentumok elhagyhatók. Hogy mi történik akkor, amikor egy függvénynek nem adunk meg argumentumot, az függvényrôl függvényre változik, és az adott függvénynél ezt bemutatjuk. Néhány awk implementáció a függvénynek átadott extra argumentumokat nem veszi figyelembe. Ugyanakkor a gawk esetén, ez az eset egy végzetes hibát fog generálni.

Amikor egy függvény meghívásra kerül, akkor az argumentumait adó kifejezések elôször teljesen kiértékelôdnek, és csak utána történik meg függvényhívás. Például az alábbi programrészletben:

i = 4
j = sqrt(i++)

a i változó értéke öt lesz mielôtt az sqrt függvény meghívódik. A függvény argumentuma négy lesz.

A függvény argumentumainak kiértékelési sorrendje nem definiált. Így, nem szabad arra számítani, hogy az argumentumok balról jobbra vagy jobbról balra értékelôdnek ki. Például:

i = 5
j = atan2(i++, i *= 2)

Ha a kiértékelés balról jobbra halad, akkor az i értéke elôször hat lesz, majd 12 és az atan2 argumentumai hat és 12 lesz. De ha a kiértékelés jobbról balra halad, akkor az i értéke elôször 10 lesz, majd 11, és az atan2 argumentumai 11 és 10 lesz.

Numerikus beépített függvények

Az alábbiakban megadjuk a számokkal dolgozó beépített függvények listáját. Az opciónális argumentumokat szögletes zárójelek veszik körül ("[" és "]").

int(x)
Ez a függvény visszaadja az x-hez legközelebbi egész számot, ami x és zérus közé esik, zérus felé csonkolva. Például, int(3) eredménye három, int(3.9) eredménye három, int(-3.9) eredménye -3 és int(-3) eredménye szintén -3.
sqrt(x)
Ez a függvény visszaadja az x pozitív négyzetgyökét. Hibát jelez ha x negatív. Így sqrt(4) eredménye kettô.
exp(x)
Ez a függvény visszaadja az x természetes alapú hatványát (e ^ x), vagy hibát jelez ha x az értelmezési tartományon kívül esik. Az x értelmezési tartománya a géped lebegôpontos ábrázoló képességétôl függ.
log(x)
Ez a függvény visszaadja az x természetes alapú logaritmusát, ha x pozitív; egyébként hibát jelez.
sin(x)
Ez a függvény visszaadja az x (radián) szinuszát.
cos(x)
Ez a függvény visszaadja az x (radián) koszinuszát.
atan2(y, x)
Ez a függvény visszaadja az y / x (radián) inverz tangensét (arctan).
rand()
Ez a függvény egy véletlen számot ad vissza. A rand által visszaadott értékek egyenletesen oszlanak el egy és zérus között. Az érték viszont soha nem zérus és nem egy. Gyakran véletlen egész számokra van szükséged. Itt egy felhasználó által definiálható függvény, ami véletlen, nem negatív, n-nél kisebb egész számokat generál:
function randint(n) {
     return int(n * rand())
}
A szorzás egy zérusnál nagyobb, és n-nél kisebb véletlen valós számot generál. Ezután egész számmá konvertáljuk (az int függvényt használva), ami zérus és n - 1 közé esik, a határokat is beleértve. Itt egy másik példa, ahol hasonló függvényt használunk egy és n közé esô számok generálására. Ez a program minden bemeneti rekordnál egy új véletlen számot nyomtat ki.
awk '
# Szimulált kockadobás
function roll(n) { return 1 + int(rand() * n) }

# 3 db hat-oldalú kockával dobunk és
# a dobott pontok összegét nyomtatjuk ki.
{
      printf("%d points\n",
             roll(6)+roll(6)+roll(6))
}'
Figyelem: A legtöbb awk implementációban, a gawk-ot is beleértve, a rand függvény ugyanattól a számtól (seed) kezd el véletlen számokat generálni, amikor az awk újraindul. Így a program minden alkalommal ugyanazt az eredményt fogja produkálni. A számok véletlenszerűek egy awk futtatás alatt, de megjósolhatók egymás utáni futtatások során. Ez hasznos lehet tesztelésnél, de ha azt akarod, hogy a programod minden futtatás során más számot generáljon, akkor más kezdô számot (seed) kell megadni minden alkalommal. Ezt az srand függvénnyel lehet elérni.
srand([x])
Az srand függvény a véletlen szám generálás kezdôpontját (seed) állítja be az x által megadott értékkel. Minden kezdôpont más véletlen számsorozathoz vezet.(11) Így ha a kezdôpont ugyanaz egy második alkalommal, akkor ugyanazt a sorozatot fogod megkapni, mint az elsô alkalommal. Ha nem adsz meg argumentumot és csak az srand() formát használod, akkor az aktuális dátumot és idôpontot használja kezdôpontként. Ez a módja annak, hogy igazi véletlen számokat generáljunk. Az srand függvény visszatérési értéke az elôzô kezdôpont értéke. Ez lehetôvé teszi a megadott kezdôpontok nyilvántartását és ugyanazon véletlen szám sorozatok generálását.

Szövegmanipuláló beépített függvények

Ebben a bekezdésben található függvények szövegeket vizsgálnak vagy változtatnak meg. Az opcionális argumentumok szögletes zárójelek között ("[" and "]") jelennek meg.

index(in, find)
Ez a függvény az in szövegben a find szöveg elsô elôfordulását keresi meg, és azt a karakterpozíciót adja vissza az in szövegen belül, ahol a find szöveg kezdôdik. Például:
$ awk 'BEGIN { print index("peanut", "an") }'
-| 3
Ha nem találja a find szöveget, akkor az index függvény zérussal tér vissza. (Az awk szövegek elsô karaktere az egyes pozíciónál található.)
length([string])
Ez a függvény a string szövegben található karakterek számát adja meg. Ha a string egy szám, akkor a szám ábrázolásához szüséges számjegyek számával tér vissza. Például, length("abcde") visszatérési értéke öt. Ezzel ellentétben, az length(15 * 35) eredménye három lesz. Miért? Nos, 15 * 35 = 525, amit szöveggé konvertál "525", amiben három karakter van. Ha nincs argumentum megadva, akkor a length függvény a $0 hosszát adja meg. Az awk régebbi verzióiban a length függvényt zárójelek nélkül is meg lehetett hívni. A POSIX szabvány ezt "helyteleníti". Ez azt jelenti, hogy ez a lehetôség végül is el fog tűnni a szabványból. Így a maximális hordozhatóság érdekében a legjobb a zárójeleket kitenni.
match(string, regexp)
A match függvény a string szövegben a leghosszabb, legbaloldalibb szövegrészletet keresi meg, ami illeszkedik a regexp reguláris kifejezésre. Azt a karakterpozíciót adja vissza, vagy indexet, ahol a szövegrészlet kezdôdik (ez egy, ha a string elején kezdôdik). Ha nem volt illeszkedés, akkor a visszatérési érték zérus. A match függvény az RSTART beépített változónak az indexet adja meg, mint új érték. Ezen kívül az RLENGTH beépített változó az illeszkedô szöveg hosszát adja meg. Ha nem volt illeszkedés, az RSTART értéke zérus, az RLENGTH értéke -1 lesz. Például:
awk '{
       if ($1 == "FIND")
         regex = $2
       else {
         where = match($0, regex)
         if (where != 0)
           print "Match of", regex, "found at", \
                     where, "in", $0
       }
}'
Ez a program olyan sorokat keres, amelyek illeszkednek a regex változóban tárolt kifejezésre. Ez a reguláris kifejezés megváltoztatható, így ha a sorban az elsô szó a `FIND', akkor a regex új értéke a sor második szava lesz. Így ha ez a bemenet:
FIND ru+n
My program runs
but not very quickly
FIND Melvin
JF+KM
This line is property of Reality Engineering Co.
Melvin was here.
az awk ezt fogja kinyomtatni:
Match of ru+n found at 12 in My program runs
Match of Melvin found at 1 in Melvin was here.
split(string, array [, fieldsep])
Ez a függvény a string szöveget vágja fel olyan darabokra, amelyeket fieldsep szöveg választ el, és a darabokat az array tömbben tárolja. Az elsô darabot a array[1] -ba teszi, a másodikat a array[2]-ba és így tovább. A harmadik argumentum, a fieldsep, egy reguláris kifejezés ami azt adja meg, hogy hol kell a string szöveget felvágni (ugyanúgy mint ahogy az FS azt adja meg, hogy hol kell a mezôket feldarabolni). Ha a fieldsep nincs megadva, akkor az FS értékét használja. A split függvény visszatérési értéke a generált szöveg darabok száma. A split függvény a bemeneti rekord mezôkre darabolásához hasonló módon vágja fel a szöveget. Például:
split("cul-de-sac", a, "-")
felvágja a `cul-de-sac' szöveget három darabba a `-' jel mentén. Az a tömb tartalma a következô lesz:
a[1] = "cul"
a[2] = "de"
a[3] = "sac"
A split függvény visszatérési értéke három lesz. Ugyanúgy mint a mezôdarabolásnál, amikor a fieldsep értéke " ", akkor a kezdô és záró szóközöket és tab karaktereket nem veszi figyelembe és az elemeket szóközök és tab karakterek (sorozatai) választhatják el. Szintén igaz, hogy ha a fieldsep értéke egy üres szöveg, akkor a szöveg minden karaktere egy külön tömb elembe kerül. (Ez egy gawk specifikus kiterjesztés.) Az awk újabb implementációi, a gawk is, megengedi, hogy a harmadik argumentum egy regexp konstans (/abc/) vagy egy szöveg legyen (s.s.). A POSIX szabvány szintén megengedi ezt. Mielôtt a szöveget felvágná, a split függvény kitörli az array tömb minden létezô elemét (s.s.). Ha a string szöveg egyik részlete sem illeszkedik a fieldsep szövegre, akkor az array tömbnek csak egy eleme lesz. Az elem értéke maga az eredeti szöveg, a string, lesz.
sprintf(format, expression1,...)
Ez a függvény azzal a szöveggel tér vissza (anélkül, hogy kinyomtatná) amit a printf függvény nyomtatna ki ugyanazokkal az argumentumokkal (see section Nyomtatás a printf kifejezéssel). Például:
sprintf("pi = %.2f (approx.)", 22/7)
a visszatérési értéke a "pi = 3.14 (approx.)" lesz.
sub(regexp, replacement [, target])
A sub megváltoztatja a target értékét. A függvény a regexp reguláris kifejezésre illeszkedô legbaloldalibb, leghosszabb illeszkedést keresi a target-en belül. Ezután az egész szöveget megváltoztatja úgy, hogy az illeszkedô szöveg részletet lecseréli a replacement szövegre. A módosított szöveg lesz a target új értéke. Ez a függvény különleges, mert a target értékét nem csak egy új érték "kiszámításához" használja, hanem meg is változtatja. Csak bizonyos kifejezések állhatnak a target helyén, úgy mint változók, mezôk vagy tömb elemek, ahova a sub el tudja tárolni a módosított értéket. Ha ez az argumentum nincs megadva, akkor az alapérték a $0. Például:
str = "water, water, everywhere"
sub(/at/, "ith", str)
az str új értéke a "wither, water, everywhere" lesz, mivel lecseréli az `at' legbaloldalibb, leghosszabb elôfordulását a `ith' szövegre. A sub függvény az elvégzett behelyettesítések száma lesz (vagy egy vagy zérus). Ha a `&' speciális karakter elôfordul a replacement-ben, akkor ez a regexp-re illeszkedô szöveg részletet jelenti. (Ha regexp egynél több szövegre illeszkedik, akkor ez a szöveg részlet változhat.) Például:
awk '{ sub(/candidate/, "& and his wife"); print }'
a `candidate' elsô elôfordulását lecseréli a `candidate and his wife' szövegre a bemeneti file minden sorában. Itt egy másik példa:
awk 'BEGIN {
        str = "daabaaa"
        sub(/a*/, "c&c", str)
        print str
}'
-| dcaacbaaa
Ez azt mutatja be, hogy a `&' hogyan képes nem konstans szöveget reprezentálni, és bemutatja, hogy mit jelent a "legbaloldalibb, leghosszabb" szabály a reguláris kifejezések illesztésében (see section Mennyi szöveg illeszkedik?). A `&' speciális karakter hatása kikapcsolható, ha egy `\' karaktert teszünk eléje. Mint mindig, ha egy szövegbe akarsz egy `\' karaktert írni, akkor kettôt kell belôle leírni. Tehát a `\\&' karaktereket kell egy szöveg konstansba beírni, hogy maga a `&' karakter jelenjen meg a csere után. Például, itt bemutatjuk, hogy hogyan lehet az elsô `|' karaktert lecserélni egy `&' karakterre minden sorban:
awk '{ sub(/\|/, "\\&"); print }'
Megjegyzés: Ahogy azt korábban írtuk a sub harmadik argumentuma egy változó, egy mezô vagy egy tömb eleme kell legyen. Az awk néhány verziója megengedi, hogy a harmadik argumentum ne egy lvalue legyen. Ebben az esetben a sub ugyanúgy viselkedik, de a csere eredményét eldobja, mivel nincs hol tárolnia. Ezek az awk verziók elfogadnák az alábbi kifejezést is:
sub(/USA/, "United States", "the USA and Canada")
A történelmi kompatibilitás miatt a gawk elfogadja a fenti hibás kódot is, de bármilyen "nem megváltoztatható" objektum, mint harmadik argumentum esetén fatális hibával leáll. Végül, ha a regexp nem egy reguláris kifejezés, akkor egy szöveggé konvertálja majd a szöveg értékét használja regexp-ként az illesztésben.
gsub(regexp, replacement [, target])
Ez a függvény hasonló a sub függvényhez, kivéve, hogy ez a függvény minden legbaloldalibb, leghosszabb, nem átfedô, illeszkedô szöveg részletet lecserél. A `g' a gsub névben a "globálist" jelenti, vagyis cseréljen mindenhol. Például:
awk '{ gsub(/Britain/, "United Kingdom"); print }'
a `Britain' szöveg minden elôfordulását lecseréli a `United Kingdom' szövegre a bemeneti rekordokban. A gsub függvény az elvégzett cserék számával tér vissza. Ha a harmadik argumentum nincs megadva, akkor a keresést és a cserét a bemeneti rekordon, $0, végzi el. Ugyanúgy mint a sub-nál a `&' és `\' karakterek speciálisak, és a harmadik argumentum egy lvalue kell legyen.
gensub(regexp, replacement, how [, target])
A gensub egy általános helyettesítô függvény. Mint a sub és a gsub a target szövegben a regexp kifejezésre illeszkedô szöveg darabot keres. Ugyanakkor a sub és a gsub függvényekkel ellentétben a módosított szöveg a függvény visszatérési értéke lesz, és az eredeti target szöveg nem lesz módosítva. Ha a how egy olyan szöveg ami a `g' vagy `G' karakterrel kezdôdik, akkor az összes illeszkedô szövegdarabot lecseréli a replacement szövegre. Minden más esetben, a how egy szám kell legyen, ami azt adja meg, hogy hanyadik illeszkedést kell lecserélni. Ha a target nincs megadva, akkor a $0-t használja. A gensub függvénynek van egy olyan szolgáltatása is, ami nem használható sem a sub sem a gsub függvényekkel: a reguláris kifejezés komponenseinek felhasználása a csereként szolgáló szövegben. Ezt úgy lehet elérni, hogy zárójelek közé kell tenni a regexp adott komponensét és a csereként szolgáló szövegben a `\n' kifejezést kell használni, ahol az n egy egy és kilenc közé esô szám. Például:
$ gawk '
> BEGIN {
>      a = "abc def"
>      b = gensub(/(.+) (.+)/, "\\2 \\1", "g", a)
>      print b
> }'
-| def abc
Ahogy azt a sub függvénynél elmagyaráztuk, két `\' karaktert kell leírni ahhoz, hogy egy `\' karakter bekerüljön a szövegbe. A csereként szolgáló szövegben a `\0' karakter sorozat a teljes illeszkedô szöveget jelenti, ugyanúgy mint a `&' karakter. Ez a példa bemutatja, hogy hogyan szabályozza a harmadik argumentum azt, hogy melyik illeszkedés lesz lecserélve.
$ echo a b c a b c |
> gawk '{ print gensub(/a/, "AA", 2) }'
-| a b c AA b c
Ebben az esetben a $0 lesz a negyedik argumentum. A gensub az új, csere utáni szöveggel tér vissza, amit átad a print-nek, hogy nyomtassa ki. Ha a how argumentum egy olyan szöveg, ami nem `g' vagy `G' karakterekkel kezdôdik, vagy egy zérusnál kisebb szám, akkor csak egy helyettesítés hajtódik végre. Ha a regexp nem illeszkedik a target egyik részére sem, akkor a gensub visszatérési értéke az eredeti, változatlan target szöveg lesz. A gensub egy gawk kiegészítés és "compatibility" módban nem használható (see section Command Line Options).
substr(string, start [, length])
Ez a függvény a string szöveg egy a start karakterpozíciónál kezdôdô és length karakternyi részszövegével tér vissza. A szöveg elsô karakterpozíciója az egy. Például, substr("washington", 5, 3) eredménye az "ing". Ha a length nincs megadva, akkor a függvény a string szövegnek a start karakterpozíciónál kezdôdô és a szöveg végéig tartó részszövegével tér vissza. Például, substr("washington", 5) eredménye az "ington". Ugyanez történik ha a length nagyobb hosszat ad meg, mint ami a start karakterpozíciótól a szöveg végéig tart. Megjegyzés: A substr függvény által visszaadott szövegnek nem lehet értéket adni. Így az alábbi kísérlet a szöveg egy részének megváltoztatására hibás:
string = "abcdef"
# ezt szeretnénk "abCDEf", de nem fog menni !
substr(string, 3, 3) = "CDE"
A substr függvényt nem lehet használni a sub vagy a gsub függvények harmadik argumentumában sem:
gsub(/xyz/, "pdq", substr($0, 5, 20))  # HIBÁS
tolower(string)
Ez a függvény a string szöveg egy másolatával tér vissza, amiben minden nagybetűt lecserél az azonos kisbetűre. Azokat a karaktereket, amelyek nem betűk, nem változtatja meg. Például, tolower("MiXeD cAsE 123") eredménye a "mixed case 123".
toupper(string)
Ez a függvény a string szöveg egy másolatával tér vissza, amiben minden kisbetűt lecserél az azonos nagybetűre. Azokat a karaktereket, amelyek nem betűk, nem változtatja meg. Például, tolower("MiXeD cAsE 123") eredménye a "MIXED CASE 123".

További információ a `\' és a `&' karakterek használatáról a sub, a gsub és a gensub függvényekben

Amikor a sub, a gsub vagy a gensub függvényen belül a `\' vagy a `&' karaktert szeretnéd használni, akkor fontos arra emlékezni, hogy az escape karakterek feldolgozásának több szintje van.

Elôször is van a lexikális szint, amikor is az awk beolvassa a programodat és felépíti a programod belsô reprezentációját, amit majd végre tud hajtani.

Ezután van a futtatási szint, amikor az awk azt ellenôrzi a csereként szolgáló szövegekben, hogy mit is kell csinálnia.

Mindkét szinten az awk ellenôrzi, hogy milyen karakter következik a `\' karakter után. A lexikális szinten escape szekvenciákat keres (section Escape szekvenciák). Így minden `\' karakterért, amit az awk majd a futtatási szinten vesz figyelembe két `\' karaktert kell megadni a lexikális szinten. Ha egy olyan karakter követi az `\' karaktert, ami nem egy érvényes escape szekvencia, akkor a Unix awk és a gawk is egyszerűen eltávolítja a `\' karaktert, és csak a követô karaktert tartja meg a szövegben. Így például, a "a\qb" szöveg a "aqb" szövegnek felel meg.

A futtatási szinten a különbözô függvények különbözô módon kezelik a `\' és a `&' karakterek használatát. A helyzet (sajnos) elég bonyolult.

Történelmileg a sub és a gsub függvények a `\&' karaktersorozatot speciálisan kezelték; ezt a sorozatot a csereként használt szövegben lecserélte a `&' karakterre. Minden más `\' karakter a csereként szolgáló szövegen belül, amit nem a `&' karakter követett, változatlan maradt. Ezt az alábbi táblázat illusztrálja:

Ez a táblázat bemutatja mind a lexikális feldolgozást, ahol a páratlan számú `\' karakterek páros számúvá válnak a futtatási szinten, és a sub által végrehajtott feldolgozást a futtatási szinten. (Az egyszerűség kedvéért a késôbbi táblázatokban csak a lexikális szinten páros számú `\' karakterrel megadott eseteket mutatjuk be.)

A probléma a történelmi megközelítéssel az, hogy lehetetlen azt az esetet megadni, amikor az illeszkedô szöveget egy `\' karakter elôzi meg.

Az 1992-es POSIX szabvány megpróbálta ezt a problémát megoldani. A szabvány azt mondja ki, hogy a sub és a gsub függvények a `\' karakter után vagy egy `\' vagy egy `&' karaktert keresnek. Ha bármelyik eset elôfordul, akkor a `\' karaktert követô karakter érintetlenül kerül be a szövegbe. Tehát a `\' és a `&' karakterek értelmezése a következô:

Ez úgy tűnik megoldja a problémát. Sajnos, a szabvány szövege szokatlanul fogalmazza ezt meg. Azt mondja, hogy a `\' karakter kikapcsolja bármely követô karakter speciális jelentését, de a speciális jelentés kivéve a `\' és a `&' karaktereket nem definiált. Ez a fogalmazás két problémához vezet.

  1. A `\' karaktert kétszer kell leírni a replacement szövegben, aminek hatására a régi awk programok nem fognak helyesen működni.
  2. Ha biztosak akarunk abban lenni, hogy az awk program hordozható, akkor a replacement szövegben minden karakter elé egy `\' karaktert kell tenni.(12)

A POSIX szabvány átdolgozás alatt áll.(13)A fenti problémák miatt, az új, módosított változat olyan szabályokat ad meg, amelyek jobban hasonlítanak a régiekhez. Az új szabály speciális eseteket definiál arra az esetre, ha egy `\' karakternek kell megelôznie az illeszkedô szöveget.

Röviden, a futtatási szinten most három speciális eset van, a `\\\&', a `\\&' és a `\&'. Ezzel ellentétben régen csak egy volt. Ugyanakkor, mint a régi szabályban, bármely `\' karakter, ami nem része a három kivételnek nem speciális, és maga a karakter jelenik meg.

A gawk 3.0-ás verziója az új POSIX ajánlást követi a sub és a gsub esetén. Jelenleg még nem lehet tudni, hogy az új ajánlás végleg bekerül-e a szabványba. A gawk jövôbeli verziói a szabványt fogják követni, bármi is legyen a végleges szabványban; ekkor ezt a könyvet is frissíteni fogjuk.

A szabályok a gensub esetén sokkal egyszerűbbek. A futtatási szinten, amikor a gawk egy `\' karaktert vesz észre, és a követô karakter egy számjegy, akkor a reguláris kifejezésben elhelyezett zárójelek a közötti illeszkedô szöveg fog megjelenni a kimenetben. Minden más esetben, akármi is legyen a `\' karakter után, maga a karakter fog megjelenni és a `\' karakter nem.

A lexikális és a futtatási szint bonyolultsága és a sub és a gsub függvények speciális esetei miatt azt tanácsoljuk, hogy ha gawk-ot használsz, akkor a gensub függvényt használd helyettesítésre.

Bemenettel és kimenettel (I/O) kapcsolatos beépített függvények

Az alábbi függvények a bemenettel vagy a kimenettel kapcsolatosak. Az opcionális argumentumok szögletes zárójelek ("[" and "]") között jelennek meg.

close(filename)
Lezárja a filename file-t, akár bemenetre vagy kimenetre lett megnyitva. Az argumentum lehet egy shell parancs is, ami az eredményt egy file-ba irányította át; ekkor a csövet zárja le. See section Bemeneti és kimeneti file-ok és csövek lezárása..
fflush([filename])
Ez a függvény kiüríti a filename-hez tartozó buffer-t, és kinyomtatja a buffer tartalmát. A filename lehet egy file neve, de egy shell parancs is lehet. Sok segédprogram buffereli a kimenetét; ami azt jelenti, hogy egy file-ba vagy a terminálra kiirandó adatokat a memóriában tartja addig, amikor is érdemes az egész adatot a kimeneti eszköznek átadni. Ez a megoldás sokkal hatékonyabb, mint amikor minden kis adatot azonnal megjelenítünk. Ugyanakkor alkalmanként fontos lehet a bufferek tartalmát kiíratni, üríteni az adott pillanatban, még akkor is ha a buffer nincs tele. Erre való az fflush függvény. A gawk is buffereli a kimenetét, és az fflush függvénnyel lehet arra kényszeríteni, hogy az adott pillanatban a buffer tartalmát kiírja. Az fflush függvényt 1994-ben adták hozzá a Bell laboratóriumban fejlesztett awk verzióhoz; a függvény nem része a POSIX szabványnak, és nem használható ha a `--posix' opció szerepel a parancssorban (see section Command Line Options). A gawk kétféle módon fejlesztette tovább az fflush függvényt. Az elsô, hogy argumentum nélkül is meg lehet hívni a függvényt. Ebben az esetben a szabványos kimenet lesz ürítve. A második, hogy az üres szöveg ("") is megadható argumentumként, amikor is minden megnyitott file vagy csô buffere ürítve lesz. Az fflush függvény zérus értékkel tér vissza ha sikeres volt az ürítés, és egy nem zérus értékkel minden más esetben.
system(command)
A system függvény teszi lehetôvé, hogy a felhasználó bármilyen az operációs rendszerben engedélyezett parancsot végrehajthasson, majd az awk program futása folytatódjon. A system függvény a command szövegben adott parancsot hajtja végre. A parancs végrehajtása által visszaadott érték lesz a függvény visszatérési értéke. Például, ha az alábbi programrészletet teszed be az awk programodba:
END {
     system("date | mail -s 'awk run done' root")
}
akkor a rendszeradminisztrátor egy levelet fog kapni, amikor az awk program befejezte a bemenete feldolgozását. A print vagy a printf átirányítása egy csôbe gyakran elég a feladat elvégzéséhez. Ha sok parancsot kell végrehajtani, akkor hatékonyabb egy csôbe nyomtatni, ami egy shell-be van átirányítva:
while (amíg van mit csinálni)
    print command | "/bin/sh"
close("/bin/sh")
Ugyanakkor ha az awk programod a felhasználótól is vár bemenetet (interaktív), akkor a system függvény jól használható nagyobb programok indítására, mint egy shell vagy egy szövegszerkesztô. Néhány operációs rendszer nem támogatja a system függvény használatát, ebben az esetben fatális hibát okoz a függvény hívása.

Interaktív és nem interaktív bufferelés

Érdemes itt megjegyezni, hogy a bufferelés zavarba ejtô is lehet ha a programod interaktív; pl. a program kommunikál a felhasználóval.(14)

Az interaktív programok általában soronként bufferelik a kimenetüket. A nem interaktív programok addig várnak amíg be nem tellik a bufferük, ami több sornyi kimenet is lehet, és csak ekkor írják ki a buffer tartalmát.

Itt egy példa a különbség bemutatására.

$ awk '{ print $1 + $2 }'
1 1
-| 2
2 3
-| 5
Control-d

Minden kimeneti sort azonnal kinyomtat. Hasonlítsd ezt össze a következô példával.

$ awk '{ print $1 + $2 }' | cat
1 1
2 3
Control-d
-| 2
-| 5

Itt addig nem ír ki semmit, amíg a Control-d billentyű kombinációt meg nem kapja, mivel minden bufferelt, és egy menetben küld el mindent a cat parancsnak a csövön keresztül.

A kimeneti bufferelés szabályozása a system függvénnyel

Az fflush függvénnyel közvetlen szabályozható az egyes file-ok vagy csövek bufferelése. Ugyanakkor sok más awk implementációban ez a függvény nem támogatott. Egy alternatív megoldás a bufferek kiürítésére, ha a system függvényt hívjuk meg egy üres szöveg argumentummal:

system("")   # kimenet ürítése

A gawk a system függvény ilyen használatát speciálisan kezeli, és van annyira okos, hogy nem futtat egy shell-t (vagy más parancsértelmezôt) egy üres paranccsal. Ezért a gawk esetén ez nem csak hasznos megoldás, de hatékony is. Bár ez a megoldás más awk implementációkban is működni fog, de nem biztos, hogy azok az awk implementációk nem indítanak el egy shell-t. (Más implementációk lehet hogy csak a szabványos kimenetet ürítik, és nem minden bufferelt kimenetet.)

Ha arra gondolsz, hogy egy programozó mit várna el, akkor egyértelmű, hogy a system függvény üríti a még ki nem nyomtatott buffereket. Az alábbi program:

BEGIN {
     print "first print"
     system("echo system echo")
     print "second print"
}

ezt kell, hogy nyomtassa

first print
system echo
second print

és nem ezt

system echo
first print
second print

Ha az awk nem üríti a buffereit a system függvény hívása elôtt, akkor az utóbbi (nem kívánt) eredményt kapnánk.

Dátumfeldolgozó függvények

Az awk programok egyik gyakori felhasználása a log file-ok feldolgozása, amelyek dátum és idô információt is tartalmaznak. Sok program a time rendszerfüggvény által megadott idôt használja a log file-okban. Ez az idô, a POSIX rendszereken, az 1970 január 1-e (UTC), éjfél óta eltelt másodpercek száma.

Azért hogy ezeket a log file-okat egyszerűbb legyen feldolgozni, a gawk két függvényt biztosít az idôbélyegek kezelésére. Mind a két függvény gawk kiterjesztés; sem a POSIX szabvány nem tartalmazza, sem más awk implementációk.

Az opcionális paraméterek szögletes zárójelek ("[" and "]") között jelennek meg.

systime()
Ez a függvény az aktuális idôt adja meg. Ez az idô, a POSIX rendszereken, az 1970 január 1-e (UTC), éjfél óta eltelt másodpercek száma. Más rendszereken más lehet.
strftime([format [, timestamp]])
Ez a függvény egy szöveggel tér vissza. Hasonló az ANSI C-ben található azonos nevű függvényhez. A timestamp által megadott idôbôl egy szöveget készít a format mint formátumleíró alapján. A timestamp ugyanabban a formában van megadva, mint amit a systime függvény visszaadna. Ha nincs megadva a timestamp argumentum, akkor a gawk az aktuális idôt veszi alapul. Ha a format argumentum nincs megadva, akkor az strftime függvény a "%a %b %d %H:%M:%S %Z %Y" szöveget fogja használni. Ez a formátum (majdnem) ugyanaz mint amit a date segédprogram használ. (A gawk 3.0-ás verziója elôtti verziókban a format argumentumot mindig meg kellett adni.)

A systime függvény lehetôvé teszi, hogy idôbélyegeket hasonlíts össze az aktuális idôponttal. Például könnyű meghatározni, hogy mennyivel korábban lett az adott log bejegyzés rögzítve.

Az strftime függvény lehetôvé teszi, hogy ember számárá is olvasható formában jelenjen meg az idôbélyeg. Hasonló az sprintf függvényhez (see section Szövegmanipuláló beépített függvények), mivel minden nem formátum leíró karaktert ugyanúgy bemásol a szövegbe és csak a formátum leírók helyeire teszi be az adott idôpont, adott komponensét.

Az ANSI C szabvány által garantált, hogy az strftime függvény az alábbi formátumleírókat támogatja:

%a
A hét napjának a rövidített neve a helyi nyelven.
%A
A hét napjának a neve a helyi nyelven.
%b
A hónap rövidített neve a helyi nyelven.
%B
A hónap neve a helyi nyelven.
%c
A helyi szokásoknak "megfelelô" dátum és idô reprezentáció.
%d
A hónap napja, mint decimális szám (01--31).
%H
Az óra (24 órás beosztásban) mint decimális szám (00--23).
%I
Az óra (12 órás beosztásban) mint decimális szám (01--12).
%j
Az év napja, mint decimális szám (001--366).
%m
A hónap, mint decimális szám (01--12).
%M
A perc, mint decimális szám (00--59).
%p
Az AM/PM jelölésnek megfelelô helyi rövidítés a 12 órás beosztáshoz.
%S
A másodperc, mint decimális szám (00--60).(15)
%U
A hét száma az évben (az elsô vasárnap, mint az elsô hét elsô napja) mint decimális szám (00--53).
%w
A hét napja, mint decimális szám (0--6). Vasárnap a zérus.
%W
A hét száma az évben (az elsô hétfô, mint az elsô hét elsô napja) mint decimális szám (00--53).
%x
A helyi szokásoknak "megfelelô" dátum reprezentáció.
%X
A helyi szokásoknak "megfelelô" idô reprezentáció.
%y
Az év az évszázadok nélkül, mint decimális szám (00--99).
%Y
Az év az évszázadokat is megadva, mint decimális szám (pl. 1995).
%Z
Az idôzóna neve vagy rövidítése, vagy semmi ha az idôzóna nem határozható meg.
%%
Maga a `%' karakter.

Ha a formátum leíró nem a fentiek közül valamelyik, akkor a viselkedés nem definiált.(16)

Informálisan, a helyi azt a földrajzi helyet jelenti, ahol a programnak futnia kell. Például az 1991 szeptember 4-ei dátum egy általános rövidítése az Egyesült Államok területén a "9/4/91". Európa sok országában a "4.9.91" rövidítést használnák. Így a `%x' a `9/4/91' szöveget produkálja ha az "US" van definiálva, míg az "EUROPE" esetén az eredmény a `4.9.91' lenne. Az ANSI C a "C"-t definiálja mint helyi beállítás (locale), amit a legtöbb C programozó használ.

A gawk csomag a strftime függvény egy "public-domain" C verzióját is tartalmazza olyan rendszerek számára, amelyek nem teljesen ANSI kompatíbilisek. Ha a gawk ezzel a verzióval lett lefordítva (see section Installing gawk), akkor az alábbi formátumleírókat is lehet használni:

%D
Ugyanaz mint `%m/%d/%y'.
%e
A hónap napja. Ha csak egy számjegybôl áll, akkor egy szóközzel kiegészítve.
%h
Ugyanaz mint `%b', fent.
%n
Új sor karakter (ASCII LF).
%r
Ugyanaz mint a `%I:%M:%S %p'.
%R
Ugyanaz mint a `%H:%M'.
%T
Ugyanaz mint a `%H:%M:%S'.
%t
Egy tabulátor karakter.
%k
Az óra (24 órás beosztásban) mint decimális szám (0-23). Ha csak egy számjegybôl áll, akkor egy szóközzel kiegészítve.
%l
Az óra (12 órás beosztásban) mint decimális szám (1-12). Ha csak egy számjegybôl áll, akkor egy szóközzel kiegészítve.
%C
Az évszázad, mint egy 00 és 99 közti szám.
%u
A hét napja, mint decimális szám [1 (hétfô)--7].
%V
A hét száma az évben (az elsô hétfô, mint az elsô hét elsô napja), mint decimális szám (01--53). A hét számának megállapítása a ISO 8601 szabványban definiált. (Ha a január elsejét tartalmazó hétbôl négy vagy több nap esik az új évre, akkor elsô hét, egyébként az elôzô év 53. hete és a következô hét lesz az elsô.)
%G
Az év az évszázaddal együtt az ISO hét szám alapján, mint decimális szám. Például, 1993 január 1, 1992 53. hetében van, így az ISO hét szám szerint az év 1992. Hasonlóan 1973 december 31, 1974 elsô hetében van, így az ISO hét szám szerint az év 1974, még akkor is ha a nap 1973-ra esik.
%g
Az év az évszázad nélkül az ISO hét szám alapján, mint decimális szám (00--99).
%Ec %EC %Ex %Ey %EY %Od %Oe %OH %OI
%Om %OM %OS %Ou %OU %OV %Ow %OW %Oy
Ezek "alternatív reprezentációi" azoknak az eseteknek amelyik csak a második betűt használnák (`%c', `%C', és így tovább). Ezeket is felismeri, de a normális reprezentációt használja.(17) (Ez a lehetôség a POSIX date segédprogrammal kompatíbilis.)
%v
A dátum VMS formátumban (pl. 20-JUN-1991).
%z
Az idôzóna eltolódás +HHMM formátumban (pl. ez a formátum a RFC-822/RFC-1036 által definiált dátum fejléchez kell).

Ez a példa a POSIX date segédprogram awk implementációja. Általában a date az aktuális dátumot és idôt nyomtatja ki egy jól ismert formátumban. Ugyanakkor, ha olyan argumentumot adsz meg ami `+' karakterrel kezdôdik, akkor a date a nem formátumleíró karaktereket közvetlenül kinyomtatja, míg az adott formátumnak megfelelôen írja ki az aktuális idôt. Például:

$ date '+Today is %A, %B %d, %Y.'
-| Today is Thursday, July 11, 1991.

Itt a gawk verziója a date segédprogramnak. Egy shell "wrapper" veszi körbe, hogy a `-u' opciót is kezelje, ami azt adja meg a date programnak, hogy UTC idôzónában adja meg az idôt.

#! /bin/sh
#
# date --- approximate the P1003.2 'date' command

case $1 in
-u)  TZ=GMT0     # use UTC
     export TZ
     shift ;;
esac

gawk 'BEGIN  {
    format = "%a %b %d %H:%M:%S %Z %Y"
    exitval = 0

    if (ARGC > 2)
        exitval = 1
    else if (ARGC == 2) {
        format = ARGV[1]
        if (format ~ /^\+/)
            format = substr(format, 2)   # remove leading +
    }
    print strftime(format)
    exit exitval
}' "$@"


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