A Unix eszközök közül nagyon sok használ
mintaillesztést, s a megadott mintára illeszkedõ adatokon
további feldolgozást hajt végre.
Vannak olyan parancsok, ahol a felhasználó adja meg a
keresendõ mintát, ilyen a grep parancs, másokban rejtve
dolgozik a mintakeresõ
algoritmus. Reguláris kifejezések használatakor
egy komplex mintát adunk meg (ez a reguláris kifejezés),
és azt vizsgáljuk, hogy a
feldolgozandó adatok melyik része illeszkedik a megadott
mintára. A reguláris kifejezések karakterekbõl
állnak, ezek közül néhány
speciális jelentest hordoz, ezeket metakaraktereknek nevezzük.
A reguláris kifejezéseket meghatározó szabályok:
SZÛRÕK
1. grep
Arra szolgál, hogy egy adott
minta elõfordulását keresse a paraméterként
megadott állományokban.
Általános formája:
$ grep mit_keressen hol_keressen
Példák.
$ grep '[tf]arka' fajl
- kiírja a fal nevû
állomány azon sorait, amelyekben a tarka vagy farka szavak
szerepelnek
$ grep '^\^' kalap
- kiírja az összes olyan
sort a kalap nevû állományból, amely ^ karakterrel
kezdõdik
$ ls -l | grep ^d
- kiírja a munkakönyvtárban
levõ összes katalógust
$ grep '^main' *.c
- kiírja a .c végû
állományok azon sorait, amelyek a main karaktersorral kezdõdnek
2. egrep
Lehetõség van arra, hogy a mintát egy állományból vegyük. Akkor érdemes ezt a lehetõséget használni, ha bonyolult mintát kell gyakran használni.
Példa.
$ cat >pattern
'[A-Z].*[\.!\?]$'
CTRL-D
$ egrep -f pattern fal
3. fgrep
karakterláncot párhuzamosan
keres
4. sort
Bemenetet soronként ASCII
kódok szerint rendezi.
-f a kis és nagybetûk
megkülönböztetése nélkül rendez
-d szótári rend
-r minden összehasonlítás
értelmét az ellenkezõjére fordítja
-u az egymás után
következõ egyforma sorok közül csak egyet hagy
5. AZ awk MINTAKERESÕ ÉS
FELDOLGOZÓ NYELV
HASZNÁLATA:
$ awk 'program' fájlnevek
A program szerkezete:
minta {tevékenység}
minta {tevékenység}
Az awk a fájlnevekben levõ bemenetet soronként beolvassa. Minden sort minden mintával összehasonlít. A sorral egyezõ mintára végrehajtja a hozza tartozó tevékenységet. Nem változtatja meg a bemeneti fájlokat. A minta is, a tevékenység is opcionális. Ha a tevékenységet elhagyjuk, az alapértelmezés szerinti tevékenység az egyezõ sorok kiírása.
pl.
$ awk '/^a/ {print}' file
- kiírja a file nevû
állomány minden olyan sorát, amelyik a-val kezdõdik
$ awk '/^a/' file
- az eredmény ugyan az
MEZÕK
Az awk minden bemenõ sort automatikusan mezõkre, azaz alapértelmezés szerint szóközökkel vagy tabulátorokkal elválasztott karakterláncokra oszt. Az awk a mezoõket $1, $2, ..., $NF nevekkel jelöli. $0 a teljes sor, változtatás nélkül. NF a mezõk száma.
pl.
$ who | awk '{print $1, $5}'
A mezõelválasztó karaktert meg lehet változtatni a -F parancsopcióval.
pl.
$ who | awk -F: '{print S1}'
KIÍRÁS
Az awk a bemeneti mezõk számán kívül más mennyiségeket is nyomom követ. Az NR beépített változó az aktuális bemeneti rekord vagy sor sorszamat adja meg.
$ awk '{print NR, $0}'
- kiírja a teljes sort és
elõtte a sor sorszamat
A print utasításban
a vesszõkkel elválasztott tételek a kimeneti mezõelválasztó
karakter, alapértelmezésben szóköz által
elválasztva kerülnek kiírásra. A C nyelvbõl
ismert printf utasítással tetszés szerint vezérelhetjük
a kimenetet.
MINTÁK
A minták lehetnek reguláris
kifejezések. Ezen kívül más módon is megadhatunk
egy mintát:
pl.
$2 == "a"
- a második mezõ
az a karaktert tartalmazza
$2 ~ /./
- a második mezõ
bármilyen karaktert tartalmazhat
$2 !~ /^a/
- a második mezõ
nem kezdõdhet az a karakterrel
length ($2) == 1 -
a második mezõ hossza 1
A ~
jel a reguláris kifejezés egyezését, a !~
jel pedig a különbözõséget jelzi.
A minta a !
jellel
tagadható:
!($2== "a")
pl.
Adott a /etc/passwd
állomány.
1. Írjuk ki minden felhasználó
azonosítóját és nevet;
2. Írjuk ki azokat a felhasználókat,
akiknek az azonosítójuk 4 karakterbõl áll.
$ awk -F: '{print $1, $5}' /etc/passwd
$ awk -F: 'length($1)==4 {print $1,
$5}' /etc/passwd
A BEGIN ÉS END MINTÁK
A BEGIN tevékenységeket az awk parancs az elsõ bemenõ sor beolvasása elõtt hajtja végre; a BEGIN-t változók inicializálására, fejléc nyomtatására, vagy az FS változónak érteket adva a mezõelválasztó kijelölésére használjuk.
Az END tevékenységet
az awk a bemenet utolsó sorának feldolgozása után
hajtja végre.
ARITMETIKA ÉS VÁLTOZÓK
Az awk rendelkezik olyan függvényekkel, amelyek a bemenõ adatokkal matematikai mûveleteket végeznek.
pl
Adott az abc nevû fájl:
123 234 345 sdghnfg
876 756 98 kjhk
12 23 435 rthjft
Adjuk össze az elsõ 3 oszlopban levõ számokat:
awk '{ s1 = s1 + $1
s2 = s2 + $2
s3 = s3 + $3 }
END {print
s1, s2, s3}' abc
A változókat nem szukaeges
deklarálni, alapértelmezés szerint kezdeti értékük
0 illetve üres karaktersor.
AZ awk BEÉPÍTETT
VÁLTOZÓI
FILENAME - az
aktuális bemeneti fájl
FS
- mezõelválasztó
karakter, alapértelmezés szerint szóköz és
tabulátor
NF
- a bemeneti rekord mezõszáma
NR
- a bemeneti rekordok száma
OFMT - a
kimenõ számok formátuma ( alapértelemezés:
%g )
OFS
- kimenõ mezõelválasztó
karakter ( alapértelmezés: szóköz )
ORS
- kimeneti rekordelválasztó
karakterlánc ( alapért: újsor )
RS
- bemeneti rekordelválasztó
karakter (alapért: újsor )
AZ awk OPERÁTOROK (NÖVEKVÕ PRECEDENCIARENDBEN)
= += -= *= /= %=
- értékadás
||
- VAGY
&&
- ÉS
!
- a kifejezés értekének
tagadása
> >= < <= == != ~ !~
- relációs operatorok,
a ~ egyezés,
a !~ nemegyezés
semmi
- karakterlánc-összekapcsolás
+ -
- összeadás, kivonás
* / %
- szorzás, osztás,
maradék
++ --
- növelés, csökkentés
AZ awk BEÉPÍTETT FÜGGVÉNYEI
cos(kif)
- a
kif koszinusa
exp(kif)
- a
kif exponenciálisa
getline()
- a következõ bemenõ
sort olvassa, 0-át
ad vissza, ha fájlvége,
1-et, ha nem
index(s1, s2)
- az
s2 helyzete az
s1 karakterláncban,
0-at ad vissza, ha nincs benne
int(kif)
- a
kif egész része
length(s)
- az
s karakterlánc hossza
log(kif)
- a
kif természetes logaritmusa
sin(kif)
- a
kif szinusza
split(s,a,c)
- az
s-t
c karakter szerint
a[1] ... a[n] mezõkre
bontja, visszaadja n-et
sprintf(fmt, ...)
- ...-ot az
fmt szerint formázza
substr(s, m, n)
- az
s karakterlánc
m-edik
karakterénél kezdõdõ
n karakteres része
VEZÉRLÉS ELLENÕRZÉS
Az if utasítás:
if (feltétel)
utasítás1
else
utasítás2
Az else
ág elmaradhat.
A for utasítás:
for (kif1; feltétel; kif2)
utasítás
A while utasítás:
while (feltétel)
utasítás
A do utasítás:
do
utasítás
while (feltétel)
A
break utasítás
az õt közrefogó while vagy do ciklusból törtenõ
azonnali kilépést okoz.
A
next utasítás
hatására beolvassa a következõ sort és
az awk program újra elölrõl kezdi a minta egyezessenek
vizsgálatát.
Az exit
utasítás hatására
a vezérlés azonnal az END mintára kerül.
TÖMBÖK
A tömböket, ugyanúgy mint a változókat nem kell elõre deklarálni, egy tömb méretét csak a gépben elérhetõ tárterület korlátozza.
pl.
a bemenetet fordított sorrendben
írja ki:
awk '{line[NR] = $0}
END { for (i=NR; i>0; i--) print line[i]}'
$*
Megjegyzés: a shell szamara
a $*
a parancssor összes argumentumát jelenti.
TÁRSTÖMBÖK ( ASSOCIATIVE ARRAY )
Adatfeldolgozásban gyakori
feladat a név-értek jellegû adatpárok értékeinek
összegzése.
Például az
Aladar 400
Bela 200
Aladar 100
Cecilia 300
Bela 700
bemenetbõl ki akarjuk számolni a nevekhez tartozó összegeket:
Aladar 500
Bela 900
Cecilia 300
Az awk erre egy érdekes módszert ad, a társtömböket. Rendszerint úgy gondoljuk, hogy egy tömb indexe csak egész szám lehet, az awk-ban azonban bármilyen érteket használhatunk tömbindexként.
Ebben az esetben a for utasítás szintakszisa:
for ( változó in tömb ) utasítás
Így az elõbbi feladat megoldása, feltételezvén, hogy a feldolgozandó állomány neve adatok:
awk '
{sum[$1]+=$2}
END {for (name in sum) print name,
sum[name] }
' adatok
FELADATOK
1. Írjuk ki a rendszeridõt a következõ módon:
xx óra yy perc zz másodperc
date | awk '{print $4}' | awk -F: '{print $1, "óra", $2, "perc", $3, "másodperc"}'
(természetesen egy sorba írva)
2. Írjuk ki n állomány tartalmat (ahol n természetes szám) úgy, hogy az egyes állományok sorai fordított sorrendben jelenjenek meg.
awk ' { line[NR] = $0 }
END { for (i=NR; i>0; i--) print line[i]
} ' $*
3. Adott n állomány,
(n természetes szám). Írjuk ki az állományok
tartalmat úgy, hogy:
- az elsõ maradjon változatlanul
- a másodiknál a sorok
mezõit fordított sorrendben ( a mezõelválasztó
karakter a : )
- a harmadikat változatlanul
- ...
awk '
BEGIN { i=-1
fnev=FILENAME
print "============================================="
print "Az allomany neve:", FILENAME
}
{ if (fnev != FILENAME)
{
i=-1*i
print "============================================="
print "Az allomany neve:", FILENAME
}
if (i>0)
print
else
{
for (j=NF; j>0; j--) printf("%s ", $j)
printf("\n")
}
fnev=FILENAME
}
END { print "============================================="
}
' $*