9 Řetězcové funkce

gsub ( regulární_výraz , náhrada ) nahradí v aktuálním záznamu všechny řetězc, vyhovující regulárnímu výrazu řetězcem náhrada , vrací počet náhrad.
gsub ( regulární_výraz , náhrada , text ) nahradí v řetězci text všechny řetězce vyhovující regulárnímu výrazu řetězcem náhrada , vrací počet náhrad.
index ( s , text ) vrací počáteční pozici prvého výskytu řetězce s v řetězci text ; není-li v něm obsažen, pak nulu.
length ( řetězec ) délka řetězce.
match ( text , regulární_výraz ) vrací počáteční pozici prvého výskytu takového řetězce v řetězci text , který vyhovuje regulárnímu_výrazu ; není-li v něm obsažen, pak nulu. Funkce nastavuje vestavěnou proměnnou RSTART, do níž uloží funkční hodnotu a proměnnou RLENGTH , která obsahuje délku prvého řetězce vyhovujícího regulárnímu_výrazu . Neobsahuje-li text žádný vyhovující řetězec, je RSTART=0 a RLENGTH=-1.
split ( text , pole ) Rozdělí řetězec text do pole podle aktuální hodnoty oddělovače záznamů FS a vrací počet prvků pole.
split ( text , pole , regulární_výraz ) Rozdělí řetězec text do pole podle oddělovače definovaného regulárním výrazem a vrací počet prvků pole.
sprintf ( formát , seznam ) vrací seznam vytisknutý podle formátu . Formát je formátovací řetězec, bude popsán u příkazů výstupu.
sub ( regulární_výraz , náhrada ) nahradí v aktuálním záznamu prvý výskyt řetězce, vyhovujícího regulárnímu výrazu řetězcem náhrada , vrací počet náhrad.
sub ( regulární_výraz , náhrada , text ) nahradí v řetězci text prvý výskyt vyhovující regulárnímu výrazu řetězcem náhrada , vrací počet náhrad.
substr ( text , pozice ) Vrací podřetězec řetězce text od pozice do konce textu.
substr ( text , pozice , délka ) Vrací podřetězec řetězce text od pozice v zadané délce .
<<vzad obsah vpřed>>

    10 Podmíněný příkaz a podmíněný výraz

    10.1 Podmíněný příkaz

if ( podmínka ) příkaz1 [ else příkaz2 ]

Jazyk awk má tyto logické operátory:

Př.:

if ( cislo >= 0 )
odmocnina = sqrt( cislo )
else
odmocnina = sqrt( -1*cislo ) "i"

V jazyce awk má přiřazovací výraz hodnotu, takže může být zapsán i v podmínce.

Př.:

if ( ( D = b**2 - 4*a*c) == 0 ){
print ("Jeden kořen")
print ("D=",D)
}
else{
print ("Dva kořeny")
print ("D=",D)
}

    10.2 Podmíněný výraz

proměnná = ( podmínka ) ? výraz1 : výraz2 ,

ekvivalentní

if (podmínka )
      proměnná = výraz1
else
      proměnná = výraz2.

Př.:

odmocnina = (cislo>=0) ? sqrt(cislo) : sqrt( -1*cislo) "i"
<<vzad obsah vpřed>>

    11 Cykly

    11.1 Cyklus while

while ( podmínka ) .

Př.:

Názvy vstupních souborů, uvedených na příkazové řádce při vyvolání awk se na začátku zpracování vytisknou takto:

BEGIN {
pocet = 1
while ( pocet <= ARGC ){
pocet++
print(ARGV[pocet])
}
}

    11.2 Cyklus do while

Cyklus do - while s testem na konci proběhne alespoň jednou:

do příkaz while ( podmínka )

Př.:

Aktuální záznam obsahuje v jednotlivých položkách názvy fotbalových klubů v pořadí jejich ligových výsledků. Je třeba nalézt , jaké pořadí má klub s názvem SPARTA:

{nalezena = 0
poradi = 0
do {
++poradi
nalezena = ( $poradi == "SPARTA")
}
while (!nalezena && poradi <= NF)
if (nalezena)
print ("Poradi SPARTY v lize:",poradi)
else
print ("Pozor! SPARTA není ve výsledcích )
}
<<vzad obsah vpřed>>

    11.3 Cyklus for

for ( [ výraz1 ]; [ podmínka ]; [ výraz 2] ) příkaz

Je ekvivalentní se zápisem
výraz1
while ( podmínka ){
     příkaz
     výraz2
}

Př.:

Příklad uvedený u cyklu while se pomocí cyklu for přepíše:

BEGIN {
for ( pocet = 1; pocet <= ARGC; pocet++ )
print(ARGV[pocet])
}

    11.4 Cyklus "for in"

for ( index in pole ) příkaz

Cyklus proběhne přes všechny prvky asociativního pole

Př.:

V asociativním poli kurz jsou uloženy kurzy měn, indexované jejich zkratkami a počítám , kolik valut dostanu za 100 Kč.

BEGIN{
kurz["DM"]=20.1; kurz["US $"]=35.1; kurz["Sk"]=1.1
print "Za 100,- Kc dostanu: "
for (mena in kurz) print  100/kurz[mena]," ", mena
}

<<vzad obsah vpřed>>

    11.5 Opuštění a opakování cyklu

Př.:

Příklad. uvedený u cyklu do while přepíšeme pomocí "nekonečného" cyklu for a příkazu break :

{nalezena = 0
poradi = 0
for (;;){
++poradi
nalezena = ( $poradi == "SPARTA")
if (nalezena || poradi =° NF)
break
}
if (nalezena)
print ("Poradi SPARTY v lize:",poradi)
else
print ("Pozor! SPARTA není ve výsledcích"
}

<<vzad obsah vpřed>>

    12 Uživatelské funkce v awk

Definují se kdekoliv v programu mimo akci:

function jméno ( [ parametr [, parametr ...]]) {
      tělo_funkce
}.

Př.:

Funkce prolozene vrací textový řetězec zadaný v argumentu zpracovaný tak, že za každý znak vloží mezeru.

function prolozene(text) {
l=length(text);
for ( i =1; i<= l; i++ )
vysledek = vysledek substr(text,i,1) " "
return vysledek
}

Př.:

Rekurzivní funkce pro výpočet faktoriálu:

function faktorial(cislo) {
return ( cislo <= 1 ? 1 : faktorial( cislo - 1 ) * cislo )
}

    13 Přerušení běhu programu

    14 Vyvolání shellovského povelu

system ( povel ) vyvolá shellovský povel a vrací jeho výstupní kód.

<<vzad obsah vpřed>>

    15 Příkazy tisku

    15.1 Print

print [ výraz [, výraz ...]]

    15.2 Printf

Formátová specifikace

%[-][ délka ][ kolik_za ] konverze
  -  zarovná výraz v poli doleva
délka délka pole, je-li na začátku délky vedoucí nula, pak se zleva doplní neplatnými nulami
kolik_za tiskne-li se řetězec, pak jeho délka, jinak počet číslic za desetinnou tečkou
konverze definuje způsob interpretace příslušného výrazu
c znak
d celé desítkové číslo
e desítkové číslo v semilogaritmickém tvaru
f desítkové číslo s desetinnou tečkou
g pokud se číslo vejde do pole, použije se konverze f, jinak e; nevýznamné nuly se netisknou
o osmičkový tvar
s znakový řetězec
x v šestnáctkovém tvaru
% znak %

Př: Tisk formátovaný příkazem printf (standardní OFMT)

printf "<%s>","Morava" <Morava> < /TD>
printf "<10%s>","Morava" <    Morava>
printf "<- 10%s>","Morava" <Morava    >
printf "<.3%s>","Morava" <Mor>
printf "<10.3%s>","Morava" <       Mor >
printf "<-10.3%s>","Morava" ; <Mor        >
printf "%d", 12.34567 12.34567
printf "%e", 12.34567 1.234567+01
printf "%g",12.34567 12.34567
printf "%4x",256 FF
printf "%04x",256 00FF
printf "%o", 9 11
<<vzad obsah vpřed>>

    15.3 Tisk do souboru - přesměrování

Př.:

Ze souboru zamestnanci.plat. chceme extrahovat položky jméno, příjmení a prémie a uložit do souboru zamestnanci.premie:

awk '{printf %s %s %s %%",$1,$2,$4}' zamestnanci.plat >> "zamestnanci.premie"

Př.:

Na konec souboru zamestnanci.premie vytvořeného v předcházejícím příkladě chceme přidat prázdnou řádku a řádku s textem "Zapsala: účetní Pavla Škrtilová":

awk '{printf "%\n%s","Zapsala: účetní Pavla Škrtilová"}' >> "zamestnanci.premie"

Př.:

Napište program , který vytvoří pro vstupních soubory bezpečnostní kopie s příponou .bak ( pro standardní vstup soubor stdin.bak).

awk '
{
if ( NR ==1 ) { # První řádka nového vstupního souboru ?
      if (FNR != 1 ) # Není prvý vstupní soubor ?
            close ( soubor )
      soubor= FILENAME ? "-" "stdin.bak : (FILENAME ".bak")
       print $0 >> soubor
}

    15.4 Tisk do roury

Př.:

Ze souboru zamestnanci.plat chceme prohlédnout jména a příjmení po stránkách:

awk '{printf $1,$2 | "more" }' zamestnanci

<<vzad obsah vpřed>>

    16 Vstup dat

Data čtená ze vstupních souborů se dělí

Př.:

Ze souboru /etc/passwd chceme vytisknout logname a úplné jméno pro všechny uživatele systému:

cat /etc/passwd | awk '
{
BEGIN {FS = ":"}
       {print $1, $5 }
}

Př.:

Soubor adresy.txt má tuto strukturu záznamu:

jméno a příjmení
ulice , číslo
město, PSČ
stát
telefon, fax, modem

jméno a příjmení
ulice , číslo
město, PSČ
stát
telefon, fax, modem

atd.

Je třeba vytisknout telefonní seznam, obsahující na každé řádce jméno a příjmení následované telefonním , faxovým a modemovým číslem (oddělovač polí je nová řádka, oddělovač záznamů prázdný znak)

cat adresy.txt | awk '
{ BEGIN
       {FS ="\n"; RS="" }
       {printf "%20s\t%40s",$1, $5}
}| lpr

Použití funkce getline

Přečtení dalšího záznamu

Př.:

"date '%YYYY'" | getline po_Kristu

uloží do proměnné po_Kristu aktuální letopočet.

<<vzad obsah vpřed>>

    17 Spolupráce awk a shellu

Text programu v awk z příkazové řádky třeba zapsat mezi apostrofy (ochrana některých znaků awk před nežádoucí interpretací shellem - např. $1, $2, ..., značící položky záznamu awk, jsou v shellovském skriptu parametry příkazové řádky Chceme-li do awk programu předat hodnotu parametru z příkazové řádky ( $1, $2,...), musíme je zamaskovat před jejich interpretací a ponechat jim význam z nadřazeném shellu:

Př.:

Soubor exper.data obsahuje v prvém sloupci nezávisle proměnnou a v druhém sloupci závisle proměnnou. Sestavte skript transf, který vytiskne nezávisle proměnnou a transformovanou závisle proměnnou. Jako parametr má řetězec udávající typ transformace : log, sin, cos.

Řešení 1
awk '{
if ( '$1' == "log" )
$2 = log($2)
if ( '$1' == "sin" )
$2 = sin($2)
if ( '$1' == "cos" )
$2 = cos($2)
print $0
}'
Řešení 2
awk "{
if ( $1 == "log" )
\$2 = log(\$2)
if ( $1 == "sin" )
\$2 = sin(\$2)
if ( $1 == "cos" )
\$2 = cos(\$2)
print \$0
}'
Řešení 3
awk '{
if ( ARGV[1] == "log" )
$2 = log($2)
if ( ARGV[1] == "sin" )
$2 = sin($2)
if ( ARGV[1] == "cos" )
$2 = cos($2)
print $0
}'

Př.:

Napište program, který na standardní výstup opíše pouze tu položku vstupního souboru, jejíž číslo je parametrem skriptu.

Řešení 1

awk '{ print $'$1' } '

Řešení 2

awk " {print \$$1 }"

Řešení 3

awk ' {print $ARGV[1] }

<<vzad obsah
_______________________________ 1Zkontrolovat na počítači tisk příkladu