Program grep je filtr, který předává na výstup řádky obsahující resp. neobsahující zadaný vzor. Název grep je zkratka pro skupinu příkazů ex editoru: globally search for regular expression and print result Volání: grep [přepínače] vzor [seznam_souborů] Přepínače: -i nerozlišuje malá a velká písmena -c tiskne pouze počet odpovídajících řádek -l tiskne pouze jména souborů -v obrací podmínku hledání (tiskne řádky, počty, jména souborů neobsahující zadaný vzor) Vzor: grep: základní regulární výraz fgrep: řetězec znaků egrep: úplný (rozšířený) regulární výraz predn_05.doc 5.11.01 1
Regulární výraz je vzor porovnávaný s daným textem a používá se pro vyhledání textu kromě programu grep (fgrep, egrep) v: editorech (vi, ex, sed) programovatelném filtru awk (nawk) Regulární výraz používá speciální znaky v jiném významu než shell ([, ],., *, $), proto se na příkazové řádce obvykle uvádí v apostrofech. Regulární výrazy mohou být základní (viz man grep) a rozšířené (viz man egrep). Nejjednodušší RE je posloupnost znaků bez speciálního významu. Příklad: $ ps -ef grep cron root 188 1 0 Oct 14? 0:00 /usr/sbin/cron honza 1963 1687 0 12:29:42 pts/2 0:00 grep cron $ predn_05.doc 5.11.01 2
Regulární výraz je definován jako jednoznakový nebo víceznakový. Jednoznakový regulární výraz: Konstrukce se porovná znak sám se sebou (libovolný znak různý od speciálních znaků a konstrukcí uvedených dále). \spec_znak se speciálním znakem (., *, [, ], \) jako takovým.. [znaky] [^znaky] - s jedním libovolným znakem. s libovolným z uvedených znaků (jedním). s libovolným znakem různým od uvedených (jedním). uvedené mezi znaky znamená interval (v obou případech). predn_05.doc 5.11.01 3
Víceznakový základní regulární výraz: Konstrukce <1znRE>* se porovná s libovolným (i nulovým) opakováním předchozího jednoznakového RE. Je-li více možností, vezme se první porovnání zleva co nejdelší. <1znRE>\{m\} s právě m opakováními jednoznakového RE (m je číslo 1 až 255) <1znRE>\{m,\} <1znRE>\{m,n\} <RE1><RE2> \(<RE>\) \n \<<RE> \><RE> ^<RE> <RE>$ s nejméně m opakováními jednoznakového RE s m až n opakováními jednoznakového RE s řetězem vzniklým spojením řetězů se kterými se porovnaly původní RE1 a RE2. s původním RE se stejným řetězem jako n-tý RE uzavřený v \( a \)dříve v tomto RE s odpovídajícím řetězem od začátku slova s odpovídajícím řetězem na konci slova odpovídajícím řetězem od začátku řádky odpovídajícím řetězem na konci řádky predn_05.doc 5.11.01 4
Příklad: $ cat t x aaa abc zba abc $ grep abc t abc zba abc $ grep '[xz]' t x zba abc $ grep '[^abc]' t x zba abc $ grep '^abc' t abc $ grep '\(.\)\1\1' t aaa $ grep '.\{4\}' t zba abc $ predn_05.doc 5.11.01 5
Víceznakový rozšířený regulární výraz Konstrukce (RE) RE* RE+ RE? RE1 RE2 se porovná pomocí závorek lze rozdělovat delší výraz na podvýrazy a ty opakovaně porovnávat pomocí *, +,? s 0 a více opakováními RE s 1 a více opakováními RE s 0 nebo 1 opakováním RE s RE1 nebo RE2 Příklad: $ cat cisla 123 +45-67 a89 ++9 $ egrep '([ ][-+]?[0-9]+) $[-+]?[0-9]+' cisla 123 +45-67 predn_05.doc 5.11.01 6
Program sed streem editor je filtr. Proto: Vstup je ze souboru nebo standardního vstupu, výstup vždy na standardní výstup. Vstupní soubor se nemění, (nelze ani použít přesměrování do vstupního souboru - proč?) Vstupní text je po řádkách načítán do vyrovnávací paměti vzorů (pattern buffer) kde je upravován a pak posílán na výstup. V některých situacích lze použít pomocnou vyrovnávací paměť (holding buffer). vstup výstup Vyrovnávací paměť vzorů Pomocná vyrovnávací paměť predn_05.doc 5.11.01 7
Formát: sed [-n] [-f prog] [příkaz] [-e příkaz] [vst.soubor] kde: -n kopírování vstupu na výstup je potlačeno (musí být explicitně prováděno příkazem p (print) -f prog soubor se seznamem příkazů příkaz příkaz pro editaci ve tvaru: [adresa1[,adresa2]]příkaz[parametry] Adresa: Není-li uvedena, provede se příkaz na všechny řádky textu. Je-li uvedena jen adresa1, provede se příkaz pouze pro tuto řádku (řádky). Jsou-li uvedeny adresy obě, definují interval řádek, pro který je příkaz proveden. Adresou může být: číslo řádky regulární výraz (obvykle /RE/, / lze nahradit \crec ) $ (poslední řádka souboru) predn_05.doc 5.11.01 8
Nejběžnější příkazy: d (delete) - zruší řádku (řádky) p (print) - opíše řádku na výstup r soubor - načte uvedený soubor a pošle ho na výstup s/re/nahrada/volby - nahradí text porovnaný s RE v náhrada se může vyskytnout: & - text, se kterým se porovnalo RE (lze potlačit \&) \n (n je číslice) - řetězec se kterým se porovnal n-tý výskyt \(REn\) v RE Příklady: $ cat t x ya aaa abc zba abc $ sed '/a/d' t x predn_05.doc 5.11.01 9
$ sed -n /a/p t ya aaa abc zba abc $ sed 's/a/1&2/' t x y1a2 1a2aa 1a2bc zb1a2 abc $ $ sed 's/\(a\)\(b\)\(c\)/\3\2\1/' t x ya aaa cba zba cba $ sed 's/a/1&2/g' t x y1a2 1a21a21a2 1a2bc zb1a2 1a2bc predn_05.doc 5.11.01 10
Program awk, nawk Programovatelný filtr vytvořený autory: Aho, Weinberger, Kernighan Základní verze později doplněna o funkce, pole a další a nazvána nawk (někde awk=nawk, v Solarisu ne!) Formát příkazu: awk [-Fc] [-f soubor_příkazů] [seznam_příkazů] [vstup._soub] kde: -Fc - definuje jiný oddělovač položek řádky (implicitně mezera) Příkazy awk: [vzor] [{ akce }] Příkazy mohou obsahovat znaky shellu a musí tvořit jeden parametr, proto se na příkazové řádce píší v apostrofech. Vstup se zpracovává po řádcích. Pro každou řádku jsou postupně ověřovány vzory a pokud vyhovují, je provedena příslušná akce. Je-li vynechán vzor, provede se akce pro všechny vstupní řádky. Je-li vynechána akce, opíší se vzorem určené řádky na výstup. Při zpracování jsou řádky rozděleny na položky $1, $2, atd., $0 je celá řádka. predn_05.doc 5.11.01 11
Vzory Vzor BEGIN END podmínka začátek,konec akce se provede: před zpracováním první řádky vstupu po zpracování poslední řádky vstupu pro řádky vyhovující podmínce podmínka pro řádky v intervalu od řádky vyhovující podmínce začátek po řádku vyhovující podmínce konec Podmínky: Regulární výraz /RE/ ve formátu egrep Výraz chápaný jako logický (0 nebo prázdný řetězec je false, ostatní hodnoty true) predn_05.doc 5.11.01 12
Výrazy jsou tvořeny pomocí operátorů jazyka C: +, -, *, /, %, ^, konkatenace (indikovaná mezerou) ++, -- (pre, post), +=, -=, *=, /=, %=, ^=, = >, >=, <, <=, ==,!=, ~,!~ (RE se porovná/neporovná s řetězem) &&,,! konstrukce var in array Příklad: $ cd /usr $ du -ks a* 1 adm 3629 apache 0 aset $ du -ks a* awk '$1 > 3000' 3629 apache $ predn_05.doc 5.11.01 13
Proměnné: $n - položky řádky oddělené oddělovačem (implicitně mezera, lze změnit přepínačem -F nebo proměnnou FS proměnná - proměnné se deklarují použitím. Podle kontextu a obsahu jsou chápány jako řetězcové nebo číselné. Proměnné mohou být jednoduché nebo pole (indexem je libovolná hodnota). Proměnné awk se používají jako v C, ne jako v shellu (nepoužívá se $ pro hodnotu). Některé předdefinované proměnné: NR - číslo zpracovávané řádky NF - počrt položek aktuální řádky FS - oddělovač položek řádky ARGC - počet argumentů na příkazové řádce kromě přepínačů a programu ARGV - pole jejich hodnot indexované od 0 do ARGC - 1 ENVIRON - pole proměnných prostředí. Indexem je jméno, hodnotou hodnota. FILENAME - jméno aktuálního vstupního souboru. predn_05.doc 5.11.01 14
Akce: Akce je program v jazyce blízkém jazyku C s těmito příkazy: if ( expression ) statement [ else statement ] while ( expression ) statement do statement while ( expression ) for ( expression ; expression ; expression ) statement for ( var in array ) statement #cyklus pres prvky pole delete array[subscript] #zruseni elementu pole break #predcasne ukonceni cyklu continue #predcasne ukonceni jedne iterace cyklu { [ statement ]... } expression # obecneji variable = expression print [ expression-list ] [ >expression ] printf format [,expression-list ] [ >expression ] predn_05.doc 5.11.01 15
Příklad: $ nawk 'BEGIN {for (e in ENVIRON) { print e "= " ENVIRON[e]}}' _INIT_PREV_LEVEL= S PS1= $ LC_MESSAGES= C LOGNAME= honza... root@solaris/root/tmp>nawk ' BEGIN { FS=":"; OFS=":" while ( getline < "/etc/shadow" > 0) shadow[$1] = $2; } /^[a-za-z0-9_]/ { $2 = shadow[$1]; printf "%s\t%s\n",$1,$0 }' \ /etc/passwd root root:egzkrrlp34mz:0:1:super-user:/root:/sbin/sh daemon daemon:np:1:1::/: sys sys:np:3:3::/:... predn_05.doc 5.11.01 16
Výstup: Implicitně jde výstup příkazů print a printf na standardní výstup. Může být pomocí: > výraz - přesměrován do souboru se jménem daným hodnotou výrazu. Soubor je při prvním použití otevřen a je zavřen na konci nebo explicitně příkazem close >> výraz - připojen do souboru výraz - poslán do programu uvedenému jako hodnota výrazu. Ve výstupu lze pokračovat dalšími přesměrováními se stejnou hodnotou výrazu. Výstup lze ukončit příkazem close(výraz) predn_05.doc 5.11.01 17
Vstup: Obvykle standardní vstup nebo vstupní soubor. Navíc lze: výraz getline[prom] vstup z příkazu zadaného hodnotou výrazu do $0 resp prom. getline[prom]<výraz vstup ze zadaného souboru getline[prom] vstup z aktuálního souboru. Pro opakování a uzavírání platí to samé jako při výstupu predn_05.doc 5.11.01 18
Funkce Aritmetické: sin(x), exp(x), log(x), sqrt(x), rand(x), srand([x]) Řetězcové: index(s,t) index výskytu t v s nebo 0, nevyskytujeli-se length[([s])] délka řetězce s match(s,ere) pozice výskytu ere v s, nastavuje RSTART a RLENGTH split(s,a[,fs]) rozdělení řetězu s do pole a podle fs resp. FS sprintf(fmt,expr,expr,...) jako printf, vrací výsledný řetězec sub(ere,repl[,in]) nahradí repl za první výskyt ere v in resp $0 gsub(ere,repl[,in]) jako sub ale všechny výskyty substr(s,m[,n]) vrací substring z s od m-té pozice o délce n tolower(s) převod na malá písmena toupper(s) převod na velká písmena predn_05.doc 5.11.01 19
Ostatní: system(výraz) volání systému, vrací návratový kód Funkce definované uživatelem: function name(args,...) { statements } Deklarace funkce může být na místě vzoru. Funkce může být použita dříve, než je deklarována. Počet formálních a skutečných parametrů nemusí souhlasit. Při volání funkce nesmí být mezi jménem a ( mezera. Návratovou hodnotu funkce lze nastavit příkazem return predn_05.doc 5.11.01 20
Příklad: $ nawk -v N=3 'function hanoi(z, na, pomoci, kolik) { > if (kolik == 1) print "z:" z " na:" na > else > {hanoi(z, pomoci, na, kolik - 1) > hanoi(z, na, pomoci, 1) > hanoi(pomoci, na, z, kolik-1)}} > BEGIN {hanoi(1,2,3,n)}' z:1 na:2 z:1 na:3 z:2 na:3 z:1 na:2 z:3 na:1 z:3 na:2 $ nawk 'function s() {return "abc"} BEGIN {print s()}' abc $ predn_05.doc 5.11.01 21