Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
Software
Awk a proměnné
31. ledna 2002, 00.00 | Minule jsme se zběžně seznámili se základními vlastnostmi awk; z příkazů, jimž rozumí, jsme však viděli jen nejzákladnější příkaz print. Dnes si ukážeme řadu dalších šikovných triků, které můžeme v awk skriptech používat.
Minule jsme se zběžně seznámili se základními vlastnostmi awk; z příkazů, jimž rozumí, jsme však viděli jen nejzákladnější příkaz print. Dnes si ukážeme řadu dalších šikovných triků, které můžeme v awk skriptech používat.Ještě pár fint s výběrem řádků
V minulém díku jsme se seznámili s použitím regulárních výrazů: jestliže jsme před skupinu příkazů, umístěnou ve složených závorkách, zapsali regulární výraz mezi lomítky, příkazy se provedly jen nad řádky, jež danému regulárnímu výrazu odpovídají; při použití dvojice regulárních výrazů šlo o řádky počínaje tím, jenž odpovídá prvému výrazu, až po druhý.
Ačkoli kompletní popis všech možností výběru řádků si necháme na konec, ukážeme si dnes ještě dvě velmi šikovné možnosti, které se každou chvíli hodí:
- zapíšeme-li před skupinu příkazů, zapsaných ve složených závorkách, slovo BEGIN, provedou se tyto příkazy před zpracováním vstupu;
- podobně pomocí slova END si můžeme vyžádat provedení odpovídajících příkazů až na konci, po zpracování všech řádků textu.
Samozřejmě, že příkazy uvedené BEGIN nebo END nejsou vázány na žádný řádek, a proto v nich nemůžeme používat výrazy $N (přesně řečeno můžeme, ale každý z nich bude representovat jen prázdný textový řetězec). Srovnejte následující příklad s odpovídajícími příklady z minulého dílu:
46 /tmp> ls -l | awk 'BEGIN { print "A jedeme" }
pipe quote> /.gz/ { print $9,"has access rights:",$1 }
pipe quote> END { print "Konec" }'
A jedeme
Kapitola4.tar.gz has access rights: -rw-r--r--
Konec
47 /tmp>
Mimochodem, chcete-li zadávat dlouhé příkazy "po kouskách", jak ukazuje tento příklad, musíte používat shell sh nebo zsh. Shell tcsh — alespoň se standardním nastavením — by vám jen vynadal "Unmatched '", takže v něm musíte celý příkaz zadat na jediném řádku:
[localhost:/tmp] ocs% ls -l | awk 'BEGIN { print "A jedeme" } /.gz/ { print $9,"has access rights:",$1 } END { print "Konec" }'
To je samozřejmě možné v libovolném shellu.
Proměnné
Skripty awk se podobají programům ve vyšším programovacím jazyce daleko více, než třeba skripty příkazu sed. Můžeme v nich používat příkazy velmi podobné příkazům jazyka C (k tomu se dostaneme zanedlouho), a můžeme v nich používat i proměnné.
Podobně jako v programovacích jazycích, i v awk má proměnná jméno, jež je kombinací písmen, číslic a podtržítek, přičemž nesmí začínat číslicí. Awk ovšem nenabízí bohatství typů, známé z programovacích jazyků: jakákoli proměnná může obsahovat číslo nebo textový řetězec, a awk tyto typy nerozlišuje.
Použijeme-li ve výrazu text jako číslo, pokusí se awk obsah řetězce nebo aspoň několika jeho prvních znaků interpretovat jako desítkově zapsané číslo; pokud se to nepodaří, je hodnota nula. Použijeme-li naopak číslo jako text, prostě se převede na string, obsahující jeho dekadický zápis.
Proměnné také není zapotřebí deklarovat: jakákoli proměnná, již jsme dosud nepoužili, obsahuje prázdný textový řetězec (a jak víme z minulého odstavce, použijeme-li ji v numerických výpočtech, je to totéž, jako kdyby obsahovala nulu).
Nejjednodušší příklad na použití proměnných by mohl vypadat třeba takto:
62 /tmp> ls -l *.tiff
-rw-r--r-- 1 ocs wheel 116880 Jan 23 17:57 BadAspectRatio.tiff
-rw-r--r-- 1 ocs wheel 50114 Jan 23 18:26 Letterbox169.tiff
-rw-r--r-- 1 ocs wheel 29518 Jan 23 17:19 PixelWidth.tiff
63 /tmp> ls -l *.tiff | awk 'BEGIN { min="-" } { print $9,"minuly",min; min=$9 }'
BadAspectRatio.tiff minuly -
Letterbox169.tiff minuly BadAspectRatio.tiff
PixelWidth.tiff minuly Letterbox169.tiff
64 /tmp>
Samozřejmě, že v praxi nejčastěji využijeme proměnné ve výrazech; těm se však budeme věnovat až příště. Dnes si ještě ukážeme pár dalších zajímavých vlastností samotných proměnných.
Pole
Proměnné v awk mohou reprezentovat jak skalární hodnoty (čísla, textové řetězce), tak i pole hodnot. Pole jsou reprezentována standardním způsobem pomocí hranatých závorek, do nichž se zapisuje index. Jestliže malinko předběhneme a řekneme si, že speciální proměnná NR vždy obsahuje číslo právě zpracovávaného řádku, mohli bychom uložit jména a velikosti všech souborů do polí následujícím jednoduchým skriptem:
{ name[NR]=$9; size[NR]=$5; }
Samozřejmě, aby to mělo dobrý smysl, musel by v témž skriptu být další blok příkazů se specifikací END, ve kterém by se obsah polí nějak zpracoval.
Velmi šikovnou vlastností awk je to, že pole mohou být indexována nejen čísly, ale libovolnými textovými řetězci. Podívejte se na následující příklad; s využitím operátoru '++' pro přičtení jedničky a příkazu for (který si sice popíšeme až později, ale toto jeho použití pro procházení všech prvků pole je snad zcela srozumitelné) spočítáme, kolik souborů v dané složce existuje pro každého uživatele (podívejte se o pár řádků výš, že jméno uživatele je ve výpisu ls -l ve třetím poli):
120 /tmp> ls -l | awk '{ cnt[$3]++ } END { for (i in cnt) print i,cnt[i] }'
root 2
ocs 20
test 4
121 /tmp>
Vidíme, že dva soubory ve složce patří uživateli "root", dvacet uživateli "ocs" a čtyři uživateli "test".
Příkaz awk sice nepodporuje vícerozměrná pole, ale ve skutečnosti s nimi můžeme bez obtíží pracovat, použijeme-li pro oddělování indexů čárky — asi takto:
{ x[1,NR]=$9; x[2,NR]=$5; }
Jak je to možné? Ale snadno: právě jsme si řekli, že awk podporuje indexování polí libovolným řetězcem; indexy, oddělené čárkou, se prostě spojí do řetězce pomocí vhodného oddělovače (standardně je to netisknutelný znak 034, ale abychom si to mohli dobře znázornit v textu, budeme předpokládat, že jde o podtržítko). Výraz x[9,NR] se tedy na třetím řádku prostě převede na x["9_3"], a je to.
Příště...
...si ještě ukážeme některé standardní proměnné, a pak se už pustíme do výrazů: popíšeme si tedy výše použitý operátor '++' a řadu dalších.
Obsah seriálu (více o seriálu):
- Obcování s ďáblem
- Obcování s ďáblem 2 - základy
- Obcování s ďáblem 3 - Práce se soubory
- Obcování s ďáblem 4 - Další práce se soubory
- Obcování s ďáblem 5 - Stále soubory, hlavně linky
- Obcování s ďáblem 6: Pár zbývajících drobností
- Obcování s ďáblem 7: Samá voda, přihořívá, hoří!
- Obcování s ďáblem 8: Jak se do shellu volá, tak se program ozývá
- Obcování s ďáblem 9: Nové finty na programy
- Obcování s ďáblem 10: Do fronty, pánové, do fronty!
- Obcování s ďáblem 11: Standardní vstup a výstup
- Obcování s ďáblem 13: Další triky
- Obcování s ďáblem 14: Vyšší škola hledání souborů
- Obcování s ďáblem 15: Příkaz find stokrát jinak
- Obcování s ďáblem 16: Co se ještě dá uvařit z příkazu find
- Obcování s ďáblem 17: Regulární výrazy
- Obcování s ďáblem 18: Speciální regulární výrazy
- Obcování s ďáblem 19: Skládání regulárních výrazů
- Obcování s ďáblem 20: Regulární výrazy se zpětnými odkazy
- Obcování s ďáblem 21:K čemu je dobrý grep...
- Zázraky ihned, nemožné na počkání: sed
- Obcování s ďáblem - další finty s příkazem sed
- Rozsáhlejší příklad se sedem
- Obcování s ďáblem: Další kouzla, aneb awk
- Awk a proměnné
- Obcování s ďáblem 27: Awk a výrazy
- Obcování s ďáblem: Awk a funkce
- Awk a příkazy
- Co je to vlastně "uživatel"?
- Vlastnictví objektů
- Přístupová práva
- Vlastník, skupina, ostatní...
- Jak je to se skupinami?
- Skupiny a uživatelé
- Scripty
- Komentáře, a volba shellu
- Pro skript může být shell cokoli!
- Shellové skripty a argumenty
- Skripty a proměnné: aritmetika
- Proměnné shellu, "dědění" hodnot
- Práce s proměnnými
- Práce se jmény souborů
- Pole hodnot
- Další triky kolem polí...
- Standardní proměnné shellu
- Základní příkazy pro skripty
- Příkaz if
- Speciální podmínkové příkazy
- Podmínky pro práci se soubory
- Jednoduchý cyklus
- Příkaz for a pomocné příkazy break a continue
- Příkaz case
- Příkazy exit a select
- Rejstřík a přehled
- Procesy
- Informace o procesech
- Další klíčová slova pro příkaz ps
- Příkaz ps: několik praktických přepínačů
- A k čemu že je "ps" dobré?
- Copak procesor, s pamětí je to horší
- Virtuální paměť
- A ještě jednou virtuální paměť
- Zpět k příkazu ps
- Skutečný žrout paměti
- Ještě jednou top
- Doplněk k topu: vm_stat
- Co to tedy všechno znamená?
- Nevychází nám dal a má dáti?
- Kam se stránky ukládají?
- Změna odkládacího disku
- Změna odkládacího disku / fstab
- Poslední poznámka k fstab
- A jak to je se soubory?
- Co vlastně příkaz lsof vypisuje?
- Příkaz lsof a obsah sloupce NAME
- SIPS - Terminál není jen pro nadšence UNIXu
- Tak nám zabili NetInfo, paní Müllerová