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.)
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.
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)
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)
sqrt(4)
eredménye kettô.
exp(x)
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)
sin(x)
cos(x)
atan2(y, x)
y / x
(radián)
inverz tangensét (arctan).
rand()
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])
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.
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)
$ awk 'BEGIN { print index("peanut", "an") }' -| 3Ha 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])
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)
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])
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,...)
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])
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 }' -| dcaacbaaaEz 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])
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])
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 abcAhogy 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 cEbben 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])
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)
tolower("MiXeD cAsE 123")
eredménye a "mixed case 123"
.
toupper(string)
tolower("MiXeD cAsE 123")
eredménye a "MIXED CASE 123"
.
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.
awk
programok nem fognak helyesen működni.
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.
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)
fflush([filename])
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)
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.
É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.
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.
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()
strftime([format [, timestamp]])
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
%b
%B
%c
%d
%H
%I
%j
%m
%M
%p
%S
%U
%w
%W
%x
%X
%y
%Y
%Z
%%
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
%e
%h
%n
%r
%R
%T
%t
%k
%l
%C
%u
%V
%G
%g
%Ec %EC %Ex %Ey %EY %Od %Oe %OH %OI
%Om %OM %OS %Ou %OU %OV %Ow %OW %Oy
date
segédprogrammal
kompatíbilis.)
%v
%z
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.