Nástroje pro práci s textem
Utility pro hledánív textu, změny a úpravy textu.
OBSAH
Grep
Cat
Cut
Sort
Comm
Split
Csplit
Expand
Unexpand
Nl
Head
Tail
Tr
Uniq
Wc
More
Join
Touch
Column
Colrm
Rev
Less
Cmp
Sed
Vi
Edit
Awk
Jot
Grep
Vypisuje a počítá řádky (ne)obsahující nějaký řetězec
-c | vypíše počet řádků ve kterých byl nalezen vzor |
-c -v | vypíše počet řádků ve kterých nebyl nalezen vzor |
-l | zobrazuje pouze jména souborů, ve kterých byl nalezen vzor |
-n | zobrazí čísla řádků obsahujících vzor |
-s | je potlačen standardní výstup, grep vrací pouze návratovou hodnotu (používá se při psaní příkazových procedur) |
-v | vypíše řádky neobsahující vzor |
-i | ignoruje rozdíly mezi malými a velkými písmeny |
-w | Vyber jen řádky ve kterých se shoduje celé samostatné slovo |
-Ačíslo | vypíše počet řádků před a řádku kde nalezl výraz |
-Bčíslo | vypíše řádku kde nalezl výraz a počet řádků za |
-Ačíslo -Bčíslo | vypíše počet řádků před,řádku kde jsi nalezl výraz a počet řádků za |
-Cčíslo | vypíše počet řádků před,řádku kde jsi nalezl výraz a STEJNÝ počet řádků za. stejné jako grep -A3 -B3 |
--collour | zvýrazní hledaný výraz jinou barvou |
Příklady
počet řádků ve kterých NEbyl nalezen vzor
grep -c zone named.conf
výsledek
93
v aktuálním adresáři zobrazuje jména souborů, ve kterých byl nalezen vzor
grep -l zone *
výsledek
named.conf
named.root
zobrazí čísla řádků obsahujících vzor a názvy
grep -n named named.conf
výsledek
3: directory "/etc/namedb";
4: pid-file "/var/run/named/pid";
vypíše 1 řádku před,řádku kde nalezl výraz "rum" a 3 řádky za
grep -A1 -B3 rum text.txt
vypíše pouze řádky , které obsahují slovo "rum" ,nevypíše řádky, které obsahují třeba "barum"
grep -w rum
v řádcích které obsahují slovo "rum" toto slovo zvýrazní
grep --colour rum
výsledek
vezmi si lopatu,k
rumpáč, sekeru a láhev
rumu
Cat
vypisuje soubory na obrazovku. Nechá se použít i na spojování
-b | čísluje neprázdné řádky |
-n | čísluje všechny řádky |
-s | pokud je více prázdných řádků za sebou, tak je zredukuje na jeden |
Příklady
vypíše soubor named.conf
cat -n named.conf
spojí soubory jedna.txt a dva.txt do souboru tri.txt
cat jedna.txt dva.txt > tri.txt
Cut
vysekává z řádků určené sloupce
-c | vysekává jednotlivé znaky |
-d | specifikuje oddelovac, podle kterého se urcují „pole" k vyseknutí (používá se spolu s -f) |
-fpocet | urcuje, kolikáté „pole" se vysekne |
-s | nevypisuj řádky neobsahující oddělovač(nějak mi nefunguje:-(() |
Příklady
vysekne 1 až 10 znak z každého řádku souboru text.txt
cut -c1-10 text.txt
vysekne 1 až 5 pole , kde oddělovač je mezera, ze souboru text.txt
cut -d´ ´ -f1-5 text.txt
vysekni 1 sloupec, nevypisuj řádky které neobsahují oddělovač, kterým je mezera
cut -f 1 -s -d' ' named.conf
Sort
program pro třídění výstupů
-t | oddělovač polí |
-kpočet | podle kolikátého pole bude výstup seřazen |
-r | obrácené(reverzní) řazení |
-b | ignoruj úvodní prázdné znaky (mez.+TAB) |
-n | řadí dle obecné numer. hodnoty |
-u | odstraní duplicity |
-f | nebudou se rozlišovat malá a velká písmena |
Příklady
seřadí podle 5 sloupce v obráceném pořadí, oddělovač je mezera
sort -t' ' -k5 -r text.txt
Comm
porovnává řádky mezi dvěma soubory. Zobrazí 2 sloupce, případně 3 sloupce pokud se použije bez parametru
-1 | v prvním sloupci zobrazí rozdíly nacházející se v druhém souboru, druhý sloupec zobrazuje společné řádky |
-2 | v prvním sloupci zobrazí rozdíly nacházející se v prvním souboru, druhý sloupec zobrazuje společné řádky |
-3 | v prvním sloupci zobrazí rozdíly nacházející se v prvním souboru, druhý sloupec zobrazuje rozdíly nacházející se v druhém souboru |
-i | stejné jako bez parametru-v prvním sloupci zobrazí rozdíly nacházející se v prvním souboru, druhý sloupec zobrazuje rozdíly nacházející se v druhém souboru
třetí sloupec zobrazuje společné řádky |
Příklady
comm text1.txt text2.txt
comm -1 text1.txt text2.txt
vytiskne pouze druhý sloupec
comm -13 text1.txt text2.txt
Split
rozřeže soubor na menší po určeném počtu řádků
formát příkazu
split číslo soubor název
číslo | určuje, kolik řádků má mít každá část (poslední část může mít řádků méně), implicitně 1000 řádků, |
soubor | jméno souboru, který má být rozdělen |
název | část názvu vygenerovaných souborů - ke každé části je k názvu souboru přidáno aa,ab,ac ... |
Příklady
rozřeže soubor text.txt na menší po 10 řádcích a pridá k názvu "mensi"
split -10 text.txt mensi
Csplit
rozřeže soubor na menší po určeném počtu řádků, případně podle obsahu
-k | nemaže soubory při chybách |
-f | použije zadanou předponu místo standartní xx |
-s | nevypisuje velikosti jednotlivých souborů |
Příklady
první soubor bude obsahovat 1 řádek, druhý soubor bude obsahovat 4 řádky, třetí bude obsahovat 9 řádků a poslední bude obsahovat řádek 10 až konec
csplit text.txt 2 5 10
ignoruje chyby, před název souborů vloží "bla",rozřeže soubor na 5 dílů(4+1), po 10 řádkách
csplit -k -f bla text.txt 5 "{4}"
rozdělí soubor na 5 dílů(4+1) po řádkách. V prvním souboru bude vše až PO PRVNÍ výskyt slova "pokus", další soubory
budou začínat řádkem ve kterém se vyskytuje slovo "pokus".V posledním souboru může být výkytů více.
csplit -k text.txt /pokus/ "{4}"
rozdělí na 4 soubory. V prvním budou všechny řádky po slovo "pokus", ve druhém řádky od slova "pokus" po slovo
"hokus", ve třetím řádky od slova "hokus" po slovo "fokus" a ve čtvrtém od slova "fokus" do konce. POZOR - bere to vždy jen první nalezený výraz, tj pokud se bude slovo
"pokus" vyskytovat i za slovem "fokus" bude ve čtvrtém souboru. Pokud je slovo "pokus" v dokumentu na začátku, bude první soubor prázdný.
csplit -k text.txt /pokus/ /hokus/ /fokus/
Expand
převádí tabelátory na mezery
-i | konvertuje pouze tabelátory před prvním znakem na řádku |
-t | počet mezer které se vloží místo tabelátoru |
Příklady
každý tabelátor nahradí 100 mezerami
expand -t 100 text.txt
Unexpand
převádí mezery na tabelátory
-i | konvertuje pouze mezery před prvním znakem na řádku |
-t | počet tabelátorů které se nahradí místo 1 mezerou |
Příklady
každých 100 mezer nahradí jedním tabelátorem
unexpand -t 100 text.txt
Nl
čísluje řádky
Příklady
nl text.txt
Head
zobrazí začátek souboru(vstupu)
-c | vypíše prvních x bajtů (pouze číslo= bajty, 1K=kB, 1M=MB) |
-n | vypíše prvních x řádek |
vypíše prvních 15 řádků
head -n 15 text.txt
Tail
zobrazí konec souboru(vstupu), defaultně 10 řádek
-f | vypisuje řádky , tak jak postupně přibívají. Výhodné při ladění, jej spustit nad logem |
-n | vypíše posledních x řádek |
-r | výpis bude řazen pozpátku, tj nejdříve poslední řádek |
Příklady
vypíše vše od 30řádku do konce
tail +30
vypíše posledních 30řádků souboru
tail -n 30
vypíše soubor a pokud přibívají zápisy ,tak je zobrazuje
tail –f /var/log/maillog
Tr
maže a nahrazuje znaky. Upozornění-program tr nahrazuje jen stejný počet znaků, pokud bude nahrazovaný text delší než je počet znaků je počet znaků vkládaných, dělá to psí kusy-viz příklady.
V tom případě raději použijte program sed
-d | znaky specifikované v prvním řetězci se vymažou, |
-c | první řetězec označuje znaky, které se nemají nahrazovat, |
-s | pokud je více stejných nových znaků za sebou, vypíše se pouze jeden, |
Příklady
vymaže všechny slova "rum" ze souboru text.txt a výsledek uloží do souboru text2.txt
tr -d 'rum' < text.txt > text2.txt
nahradí malá písmena v souboru text.txt velkými
tr '[:lower:]' '[:upper:]' < text.txt
POZOR-vysledek bude rummm, tj 4 a 5 znak se nahradi poslednim znakem slova rum
tr "pokus" "rum" < txt
Uniq
Vyjme duplicitní řádky ze souboru(vstupu)
-c | v prvním sloupci bude počet výskytů |
-d | vypíše jen vícenásobné řádky |
-i | ignoruje při porovnání malá/velká písmena |
-f | vynechá porovnávání prvních x polí |
-s | vynechá porovnávání prvních x znaků |
Příklady
vypíše všechny řádky, duplicitní vypíše jen jednou a před všema je počet výskytů
uniq -c text.txt
vypíše jen vícenásobné řádky
uniq -d text.txt
Wc
spočítá slova či znaky v souboru (vstupu)
-m | vypíše počet znaků |
-l | vypíše počet řádek |
-w | vypíše počet slov |
-c | vypíše velikost v bytech |
Příklady
počet znaků
wc -m text.txt
počet slov
wc -l text.txt
More
prohlížení souborů (výstupů) s možností listování. Používá se pokud se výstup nevejde najednou na obrazovku.
b | návrat o stránku zpět |
/ | hledání v textu |
n | zopakuje poslední zadaný příkaz |
= | vypíše čísla řádku které vidíte na obrazovce |
page up | o stránku výše |
page down | o stránku níže |
q | konec |
Join
spojuje dohromady soubory podle zadaného sloupce, který musí být v obou souborech stejný,
výstupem je seznam polí oddělených čárkami nebo mezerami, příp. zapsaný do více parametrů
tvar pole: n.f resp. 0
implicitně: první pole je klíč, výpis všech polí po řadě, oddělovačem je posloupnost bílých znaků
t 'znak' | oddělovač polí |
{1|2} f | číslo klíčového pole v souboru 1 resp. 2 |
a n | ze souboru n se berou i nespárované řádky |
v n | ze souboru n se berou jen nespárované řádky |
e str | náhrada za chybějící pole |
o list | přesný tvar výstupu |
příklad
spojí dva soubory, oddělovačam je čárka
join -t ',' soubor1 soubor2
soubor1
1,buřt
2,klobása
3,kafe
soubor2
1,100 korun
2,35 korun
3,15 korun
výsledek
1,buřt,100 korun
2,klobása,35 korun
3,kafe,15 korun
Touch
mění datum poslední modifikace souboru a pokud
soubor neexistuje, je vytvořen nový s nulovou délkou
Příklad
použít tento čas
touch -t MMDDhhmm[[SS]RR][.ss]
vytvoř soubor text.txt
touch text.txt
Column
formátuje text do úhledných sloupců
Příklad
column –t text.txt
Colrm
vystřihává určený počet znaků ze vstupu
Příklady
vystřihne prvních 20 znaků z každé řádky
arp -a | colrm 20
Rev
vypíše řádky pozpátku, tj poslední znak na řádce dá na začátek a obráceně
Příklady
rev text.txt
Less
vstup opisuje na výstup po stránkách, lepší a novější varianta příkazu more
mezera | posun o stránku vpřed |
b | posun o stránku zpět |
q | konec programu |
:n | skočí na následující soubor uvedený na příkazové řádce |
/řetězec | hledat řetězec směrem dopředu |
?řetězec | hledat řetězec směrem dozadu |
n hledat | další výskyt řetězce (v původním směru hledání) |
N hledat | další výskyt řetězce v opačném směru, než bylo zadáno původní hledání |
F | čeká a zobrazuje přírustky v souboru - obdoba příkazu tail -f soubor |
Cmp
porovnává dva soubory po jednotlivých bajtech, ohlásí první rozdílný bajt
-s | potlačení výstupu o nalezených odchylkách |
Sed
dávkový editor textu. Prakticky to znamená, že dokáže v již existujícím textu
(at již v souboru, nebo v jakémkoliv vstupu) dávkově nahrazovat, vystřihávat, vkládat nebo vyhledávat
řetězce znaků.Sed postupně načítá ze vstupního proudu dat jednotlivé řádky. Vyhoví-li řádek adrese, tak jej uloží do prostoru pro vzorky,
který pak zpracovává podle nastavených příkazů.
Adresou mohou být vzorky, nebo rozsah podle čísel řádku.Má takové možnosti, že je umí asi jen málokdo všechny použít a využít.
Pokusím se udělat nějaký výcuc a ukázat co nejvíce příkladů.Sám v mnoha věcech tápu.
jsou 2 možnosti volání programu sed
sed [volby] 'prikaz' [soubor-y]
sed [volby] -f script [soubor-y]
Volby
-e | příkaz následující argument je příkaz (použití při více příkazech) |
-f | říká, že následuje soubor, který obsahuje program (příkazy editoru) |
-n | potlačení standardního výstupu (neplatí na řádky s příkazem p a s s parametrem p) |
-r | ve scriptech použity rozšířené regulární výrazy |
-s | nebere soubory jako jeden spojitý dlouhý proud, ale jako oddělené |
Syntaxe programu
[adresa1][,adresa2][!]'příkaz'[argumenty]
Adresa-říkáme programu, které části textu budeme upravovat
adresovat můžeme číslem řádku, nebo regulárním výrazem.
žádná adresa - všechny řádky
jedna adresa - všechny řádky vyhovující adrese
dvě adresy - všechny řádky vždy od výskytu adresy1 až do výskytu adresy2
adresa následovaná ! - všechny řádky nevyhovující zadané adrese
Příklady:
1 - jen 1. řádek
100,$ - všechny řádky mezi 100. a posledním (včetně)
/pes/ - všechny řádky ve kterých se vyskytuje slovo pes
/^pes/,/^los/! - všechny řádky mimo řádků mezi pes a los
Řídící struktury
! instrukce umistěné na tomto řádku budou aplikovány na všechny řádky
kromě řadků vybraných adresou, ktera je čássti příkazu.
{} pokud je skupina instrukcí uzavřena do {}, pak jedna adresa (nebo
dvojice adres) vybere řádek, na kterou se aplikuje celá skupina
instrukcí.
Příkazy
editující příkazy, které modifikují text.
Základní editace
i\ | vloží text před řádek pokud není uvedena adresa text se připojí za každý řádek(nemůže mít 2 adresy), připojovaný text musí končit \ |
a\ | připojí text za řádek chování stejné jako předcházející |
c\ | vybrané řádky jsou změněny tak, že obsahují nový text |
d | smaže řádky |
s (n,g,p,w) | vyhledávání. "g" na konci způsobí nahrazení vyhledaných znaků druhým výrazem |
y | přeloží znaky |
Informace o řádcích
= | zobrazí číslo řádku |
l | zobrazí řídící znaky v ASCII |
p | zobrazí řádek |
Vstupně/výstupní zpracování
n | přeskočí aktuální řádek a přesune se na další |
r | načte obsah jiného souboru ze vstupu a připojí jej k vybranému řádku |
w | zapíše vstupní řádky do jiného souboru |
q | ukončí skript sed |
Kopírování a vkládání
h | kopíruje prostor pro vzorky do schránky (tu přepíše) |
H | kopíruje prostor pro vzorky do schránky (k té přidá) |
g | vyvolá obsah schránky, smaže prostor pro vzorky |
G | vyvolá obsah schránky, přidá k prostoru pro vzorky |
x | vymění obsah schránky a prostor pro vzorky |
Příkazy pro větvení
b | skočí na značku (ve skriptě označenou :značka), nebo na konec skriptu |
t | stejně jako příkaz b, ale skočí až po provedení substituce |
Zpracování vícenásobného vstupu
N | načte jiný vstupní soubor (vytvoří se vložený nový řádek) |
D | smaže až po vložený nový řádek |
P | tiskne až po vložený nový řádek |
Příklady
MEZERY V SOUBORU:
za každý řádek přidá volný řádek
sed G
za každý řádek přidá volný řádek a navíc zajistí, že nikde nebudou dva volné řádky za sebou
sed '/^$/d;G'
za každý řádek přidá dva volné řádky
sed 'G;G'
odstraní každý druhý řádek
sed 'n;d'
vloží prázdný řádek před každý řádek, který obsahuje "potvora"
sed '/potvora/{x;p;x;}'
vloží prázdný řádek za každý řádek, který obsahuje "potvora"
sed '/potvora/G'
vloží prázdný řádek před i za každý řádek, který obsahuje "potvora"
sed '/potvora/{x;p;x;G;}'
ČÍSLOVÁNÍ:
očísluje všechny řádky v souboru (zarovnání vlevo). Použití tabulátorů (viz. poznámka o \t níže) zajistí odsazení.
sed = filename | sed 'N;s/\n/\t/'
očísluje řádky v souboru (čísla vlevo, zarovnání vpravo)
sed = filename | sed 'N; s/^/ /; s/ *\(.\{6,\}\)\n/\1 /'
očísluje řádky v souboru jen pokud řádek není prázdný
sed '/./=' filename | sed '/./N; s/\n/ /'
spočte řádky (namísto "wc -l")
sed -n '$='
PŘEVODY TEXTU A NAHRAZOVÁNÍ:
# V UNIXu: převede DOSové nové řádky (CR/LF) na Unixový formát.
předpokladá že řádky konči CR/LF
sed 's/.$//'
v bash a v tcsh stiskni Ctrl-V, poté Ctrl-M
sed 's/^M$//'
pracuje s ssed, gsed 3.02.80 a vyšší
sed 's/\x0D$//'
V UNIXu: převede Unixové nové řádky (LF) na DOSový formát.
sed 's/$'"/`echo \\\r`/"
V DOSu: převede Unixové nové řádky (LF) na DOSový formát.
sed "s/$//" nebo sed -n p
V DOSu: převede DOSové konce řádek (CR/LF) na Unixový formát.Funguje pouze s editorem sed z UnxUtils, verze 4.0.7 a vyšší.
sed "s/\r//" infile >outfile
smaže prázdné místo (mezery, tabulátory) na začátku každé řádky,zarovná celý text vlevo
sed 's/^[ \t]*//'
smaže prázdné místo (mezery, tabulátory) na konci řádky
sed 's/[ \t]*$//'
smaže prázdné místo (mezery, tabulátory) ze začátku i z konce
sed 's/^[ \t]*//;s/[ \t]*$//'
vloží 5 mezer na začátek každé řádky
sed 's/^/ /'
zarovná celý text vpravo, na celkovou šířku 79 znaků ve sloupci- zarovná na 78 znaků + 1 mezera
sed -e :a -e 's/^.\{1,78\}$/ &/;ta'
vycentruje celý text do středu 79 znakového sloupce. První způsob počítá mezery na začátku a na konci jako normální znak, druhým jsou mezery na začátku odstraněny.
prohodí (najde a nahradí) "foo" a "bar" na každé řádce
sed -e :a -e 's/^.\{1,77\}$/ & /;ta' nebo
sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\( *\)\1/\1/'
nahradí jen první výskyt na řádce
sed 's/foo/bar/'
nahradí jen čtvrtý výskyt na řádce
sed 's/foo/bar/4'
nahradí všechny výskyty na řádce
sed 's/foo/bar/g'
nahradí předposlední výskyt
sed 's/\(.*\)foo\(.*foo\)/\1bar\2/'
nahradí poslední výskyt
sed 's/\(.*\)foo/\1bar/'
nahradí "foo" výrazem "bar" JEN na řádkách, které obsahují "baz"
sed '/baz/s/foo/bar/g'
nahradí "foo" vy$razem "bar" JEN na řádkách, které neobsahují "baz"
sed '/baz/!s/foo/bar/g'
nahradí "scarlet", nebo "ruby", nebo "puce" výrazem "red" -větsina sedů
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g'
nahradí "scarlet", nebo "ruby", nebo "puce" výrazem "red" -pouze GNU sed
gsed 's/scarlet\|ruby\|puce/red/g'
bezpečné nahrazování,aby se nám při nahrazování 'rum' za tuzemak' nepoškodilo třeba takové "brumla"
sed -e 's/[[:<:]]rum[[:>:]]/tuzemak/g'
vypíše soubor od konce (namísto "tac")
sed '1!G;h;$!d' nebo sed -n '1!G;h;$p'
vypíše řádky od konce (namísto "rev")
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
spojí každé dvě řádky (jako "paste")
sed '$!N;s/\n/ /'
pokud řádka končí zpětným lomítkem připojí následující řádku
sed -e :a -e '/\\$/N; s/\\\n//; ta'
pokud řádka začíná rovnítkem připojí ji k předchozí řádce a nahradí "=" mezerou
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
přidá čárky k číslům - změní "1234567" na "1,234,567"
sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta'
přidá mezery k čislům - změní "1234567" na "1 234 567"
sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1 \2/;ta'
ostatní sedy přidá prázdnou řádku po každé páté řádce (po 5, 10, atd.)
sed 'n;n;n;n;G;'
VYPSÁNÍ URČITÝCH ŘÁDEK:
vypíše prvních 10 řádek v souboru (namísto "head -n 10")
sed 10q
vypíše první řádku souboru (namísto "head -n 1"
sed q
vypíše posledních 10 řádek v souboru (namísto "tail")
sed -e :a -e '$q;N;11,$D;ba'
vypíše poslední 2 řádky souboru (namísto "tail -n 2")
sed '$!N;$!D'
vypíše poslední řádku souboru (namísto "tail -n 1")
sed -n '/VZOR/h;$g;$p' '
vypíše pouze poslední řádku odpovídající vzoru
sed '$!d' nebo sed -n '$p'
vypíše předposlední řádku v souboru pro 1-řádkový soubor vypíše prázdnou řádku
sed -e '$!{h;d;}' -e x
vypíše předposlední řádku v souboru pro 1-řádkový soubor vypíše řádku
sed -e '1{$q;}' -e '$!{h;d;}' -e x
vypíše předposlední řádku v souboru pro 1-řádkový soubor nevypíše nic
sed -e '1{$d;}' -e '$!{h;d;}' -e x
vypíše pouze řádky, které obsahují "regexp" (namísto "grep")
sed -n '/regexp/p' nebo sed '/regexp/!d'
vypíše pouze řádky, které NEobsahují "regexp" (namísto "grep -v")
sed -n '/regexp/!p' nebo sed '/regexp/d'
vytiskne řádku před tou, která obsahuje "regexp"
sed -n '/regexp/{g;1!p;};h'
vytiskne řádku po té, co obsahuje "regexp"
sed -n '/regexp/{n;p;}'
vytiskne číslo řádky obsahující "regexp", řádku před ní, jí samotnou a řádku po ní (podobně "grep -A1 -B1")
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h
grep pro AAA, BBB a CCC (v libovolném pořadí)
sed '/AAA/!d; /BBB/!d; /CCC/!d'
grep pro AAA, BBB a CCC (v tomto pořadí)
sed '/AAA.*BBB.*CCC/!d'
grep pro AAA, nebo BBB, nebo CCC (namísto "egrep")
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
vypíše odstavec obsahující AAA (odstavce jsou odděleny prázdnými řádkami)
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'
vypíše odstavec obsahující AAA, BBB a CCC (v libovolném pořadí)
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'
vypíše odstavec obsahující AAA, nebo BBB, nebo CCC
sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
vypíše jen řádky s 65 znaky, nebo víc
sed -n '/^.\{65\}/p'
vypíše jen řádky s méně než 65 znaky
sed -n '/^.\{65\}/!p' nebo sed '/^.\{65\}/d'
vypíše soubor od "regexp" do konce
sed -n '/regexp/,$p'
vypíše část souboru dle čísla řádek (řádky 8-12, včetně)
sed -n '8,12p' nebo sed '8,12!d'
vypíše řádku číslo 52
sed -n '52p' nebo sed '52!d' nebo sed '52q;d'
počínaje 3-tí, vypíše každou sedmou řádku
sed -n '3,${p;n;n;n;n;n;n;}'
vypíše část souboru mezi dvěma výrazy (včetně)- pozor na VELKÁ a malá písmena
sed -n '/Iowa/,/Montana/p'
MAZÁNÍ VYBRANÝCH ŘÁDEK:
vypíše vše AŽ na oblast mezi "Iowa" a "Montana"
sed '/Iowa/,/Montana/d'
smaže duplicitní, po sobě jdoucí řádky ze souboru (namísto "uniq").První řádka v řade duplicitních zůstane, ostatní jsou smazány.
sed '$!N; /^\(.*\)\n\1$/!P; D'
smaže duplicitní řádky nejdoucí po sobě. Pozor na přetečení bufferu,jinak užijte GNU sed.
sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'
smaže všechny řádky výskytující se jednou (namísto "uniq -d")(soubor musí být seřazen)
sed '$!N; s/^\(.*\)\n\1$/\1/; t; D'
smaže prvních 10 řádek v souboru
sed '1,10d'
smaže poslední řádku
sed '$d'
smaže poslední dvě řádky
sed 'N;$!P;$!D;$d'
smaže posledních deset řádek
sed -e :a -e '$d;N;2,10ba' -e 'P;D' nebo
sed -n -e :a -e '1,10!{P;N;D;};N;ba'
smaže každou osmou řádku
sed 'n;n;n;n;n;n;n;d;'
smaže řádky obsahující "pattern"
sed '/pattern/d'
smaže všechny prázdné řádky ze souboru (jako "grep '.' ""
sed '/^$/d' nebo sed '/./!d'
smaže všechny po sobě jdoucí prázdné řádky až na první dvě
sed '/^$/N;/\n$/N;//D'
smaže prázdné řádky na začátku souboru
sed '/./,$!d'
smaže všechny prázdné řádky na konci souboru
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}'
smaže poslední řádku všech odstavců
sed -n '/^$/{p;h;};/./{x;/./p;}'
výmaz řádek od řádky 17 do řádky na níž je řetězec 'foo'
sed 17,/foo/d
SPECIÁLNÍ POUŽITÍ:
přidá znak "> " na začátek každé řádky - citace zprávy
sed 's/^/> /'
smaže úvodní "> " ze začátku každé řádky - zrušení citace
sed 's/^> //'
odstraní většinu HTML tagů
sed -e :a -e 's/<[^>]*>//g;/zipup.bat
odstraní většinu HTML tagů
dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat
Vi
Spuštění
vi soubor.txt
Lze použít volby -r (recovery) a případně -R (Read-only).
Editor vi pracuje ve dvou základních režimech: v příkazovém režimu nebo v režimu vkládání. Do režimu vkládání se lze přepnout některým z vkládacích příkazů, zpět do příkazového režimu pomocí klávesy ESC.
Základní příkaz pro začátek editace je a nebo i, uložíme a opustíme editor příkazem ZZ.
Pohyby kursoru
h nebo šipka vlevo | kursor vlevo
|
l nebo šipka vpravo | kursor vpravo
|
k nebo šipka nahoru | kursor nahoru
|
j nebo šipka dolů | kursor dolů
|
Ctrl-f | o stránku vpřed
|
Ctrl-b | o stránku zpět
|
Ctrl-d | o 1/2 stránku vpřed
|
Ctrl-u | o 1/2 stránku zpět
|
0 | na začátek řádky |
| | (svisla cara) na začátek řádky |
^ | na prvni znak řádky různý od mezery |
_ | (podtrzeni) totéž |
$ | na posledni znak řádky |
w | (word) na nejbližší začátek slova vpravo |
e | (end) na nejbližší konec slova vpravo |
b | (back) na nejbližší začátek slova vlevo |
W | (word) na nejbližší začátek dlouhého slova vpravo |
Modifikace souboru
i | začne vkládat znaky před pozici kursoru |
a | začne vkládat znaky za pozici kursoru |
I | začne vkládat znaky na začátek řádku |
A | začne vkládat znaky na konec řádku |
U | odejmi všechny změny učiněné v aktuální řádce(undo) |
u | zrušení právě provedené změny (undo) |
o | vložení nového řádku pod aktuální a začátek vkládání |
O | vložení nového řádku před aktuální |
Enter | vložení nového řádku |
:r | soubor vložíme na aktuální pozici obsah externího souboru |
:10,13t20 | (copy)vložení řádek 10-13 za řádku 20 |
:4,18m21 | (move) řádky 4-18 přesunout za řádku 21 |
:s/old/new/ | v aktualni řádce misto "old" dosadi "new" |
:/old/s//new/ | najde nejbližši následující vyskyt "old" a nahradí ho "new" |
:/old/s/old/new/ | najde nejbližši následující vyskyt "old" a nahradí ho "new" |
:s/old/new/g | v aktualni řádce všechny vyskyty "old" nahradí "new" |
:1,$s/old/new/g | v cele pracovní paměti vsechny vyskyty "old" nahradí "new" |
| |
r | znak1 nahrazení jednoho znaku |
R | přepnutí do přepisovacího režimu |
x | smazání jednoho znaku napravo |
X | smazání jednoho znaku nalevo |
dd | smazání řádku (a vložení do bufferu) |
dG | smazání od aktuální řádku a zbytku souboru až do konce |
dH | smazání od aktuální řádku a zbytku souboru až do začátku |
D | smazání od aktuální pozice kurzoru až po konec řádku |
p | vložení textu z bufferu za pozici kursoru |
P | vložení textu z bufferu před pozici kurzoru |
yy | vložení aktuálního řádku do bufferu |
10x | vymaž 10krát znak napravo-číslo před příkazem udává, kolikrát se bude příkaz opakovat |
Hledání textu
/vzor Enter | hledání vpřed v celém souboru |
?vzor Enter | hledání vzad v celém souboru |
/ Enter | znovu hledání vzoru vpřed v celém souboru |
? Enter | znovu hledání vzoru vzad v celém souboru |
n | znovu hledání vzoru stejným směrem v celém souboru |
N | znovu hledání vzoru, ale opačným směrem v celém souboru |
fc | hledání vpřed v řádce, kurzor se zastaví na c |
Fc | hledání vzad v řádce, kurzor se zastaví na c |
; | znovu hledání vpřed v řádce |
, | znovu hledání vzad v řádce |
Několik dalších příkazů
:q | ukončení editoru |
:w | uložení aktuálního souboru |
:wq | nebo ZZ nebo :x ukončení a uložení |
:wq | soubor uložit jako |
:q! | ukončení bez uložení |
| |
:set number | nastaví číslování řádků |
:set nonumber | vypne číslování řádků |
:set list | nastaví viditelné znaky-konec řádku jako $ , escape jako ^[ , tabelator jako ^I |
:set nolist | zruší výše uvedené |
:f | vypíše číslo řádky |
Edit
editor který má uživatelsky příjemnější rozhraní než VI
Zjednodušená nápověda je na horní straně obrazovky, takže ji nebudu popisovat, jen upozorním, že klávesy je třeba dávat s Ctrl.
edit text.txt
nebo jen
ee text.txt
Jot
je nástroj který dokáže generovat rozsahy znaků. Výhodné pro scripty
Pozor- občas se chová trochu jinak, než by člověk očekával
-p | číslo přesnost na x desetinných míst |
-b | slovo zopakuje slovo x krát |
-r | vypíše náhodné čísla |
-c | vypíše ASCII znaky |
vypíše 5x slovo "test"
jot -b test - 1 5 nebo
jot -b test 5
výsledek
test
test
test
test
test
rozdelí 0-50 na 6 dilu(vcetne nuly)
jot 6 0 50
výsledek
0
10
20
30
40
50
rozdělí 10-50 na 5 dílů
jot 5 10 50
výsledek
10
20
30
40
50
vezme první a poslední výraz
jot 2 10 50
výsledek
10
50
vezme první, prostřední a poslední výraz
jot 3 10 50
výsledek
10
30
50
vypíše rozsah 1-5
jot - 1 5
výsledek
1
2
3
4
5
vypíše 5 náhodných čísel
jot -r 5
výsledek
65
11
35
79
44
vypíše ASCII znaky- zde začíná na znaku "a" a vypíše 26 následujících (abecedu)
jot -w %c 26 a
výsledek
a
b
..
y
z
vypíše slovo "text" a za něj vloží čísla 1-5
jot -w text - 1 5
výsledek
text1
text2
text3
text4
text5
vypíše 5 náhodných písmen z rozsahu a-z
jot -r -c 5 a z
výsledek
r
s
w
l
f
Awk
převzato s laskavým svolením pana Hanzlíka (franta(zav)hanzlici(tecka)cz)
Awk je programovací jazyk pro práci s textem. V textově orientovaném UNIXu
jej používáme také pro automatickou konstrukci příkazů, příkazových souborů
a předzpracování vstupních dat. Název Awk pochází ze jmen jeho autorů: Alfred
V.
Aho, Peter J.
Weinberger a Brian W.
Kernighan.
Interpretem tohoto jazyka je příkaz (program)
awk. Jeho verzí se
však vyskytuje více. Nejvíce funkcí má zřejmě implementace
awk z projektu
GNU (
gawk) a verzi 3.1.x je následující text věnován. Tato implementace má
všechny rysy podle POSIX 1003.2 a navíc některá rozšíření.
Použití awk a spuštění programu: program na cmdline n. v souboru
Struktura programu : vzorek{akce}
Záznamy a položky(records a fields:$1-$NF): proměnné RS,FS,NR,NF,$0,$1,..
Výstup: funkce print, printf, proměnné ORS,OFS; přesměrování výstupu
BEGIN a END: speciální vzorky vykonávané před/po zprac. vstup. souboru
Akce: posloupnost příkazů oddělených novým řádkem n. znakem středník
Proměnné, výrazy a přiřazení: real čísla a řetězce, převody mezi nimi
Regulární výrazy: BRE i ERE, uzavřené v lomítkách
Relační výrazy, relační operátory: <, > , == , != , >= , <=
Kombinace vzorků: booleovské operátory && , || , ! (NOT - negace)
Interval určený vzorky: /start/,/stop/ - interval, pro který se vykoná akce
Identifikátor položky jako proměnná: $(i+1)=NR
Příkazy pro řízení toku: if,while,do,for,break,continue,next,delete,exit
Pole: asociativní, n-rozměrná
Funkce (vlastní): function jméno(seznam_parametrů) {příkazy }
Interní proměnné awk: FILENAME,FNR,FS,NF,NR,OFS,ORS,RS,...
Vstupní a výstupní funkce: close,getline,next,print,printf,system,...
Numerické funkce:cos,sin,rand,int,exp,log,sqrt,...
Řetězcové funkce: asort,asorti,gensub,gsub,sub,substr,match,index,length,split,sprintf,strtonum,tolower,...
Časové funkce:mktime,strftime,systime
Funkce na manipulaci s bity: and,or,compl,xor,lshift,rshift
Funkce pro podporu internacionalizace ( řetězce _"..." )
Číselné konstanty osmičkové a šestnáckové soustavy ve stylu C: 011 a 0xF0
Řetězcové konstanty: uzavřené do uvozovek. escape posloupnosti: \n,...
Speciální soubory: /dev/stderr,/dev/fd/n,/inet/tcp/lport/rhost/rport
Volby GNU awk: krátké (POSIX) i dlouhé (GNU)
Proměnná AWKPATH: nastavíme seznam cest k adresářům s programy
GNU awk rozšíření: ESC posloup., systime+strftime,AWKPATH,jména zvl. soub,některé proměnné,...
Použití awk
Příkaz se spouští následujícím způsobem:
awk program [soubory]
Program můžeme také číst ze souboru, potom zadáme:
awk -f soubor [soubory]
Program awkčte řádky buď ze zadaných souborů nebo ze standardního
vstupu. Výstup směřuje na standardní výstup.
Struktura programu
Program pro awkse tvoří posloupností příkazů vzorek-akce a volitelně definic funkcí
ve tvaru:
vzorek {akce - příkazy}
function jméno_funkce(seznam_parametrů){příkazy}
V každém řádku čteném ze vstupu se hledá určený
vzorek. Pokud se
najde, provede se s řádkem zadaná
akce. Poté, co se použijí všechny
vzorky, přečte se ze vstupu další řádek a operace se opakují.
Jak
vzorek, tak
akce se smí vynechat. Nelze však
vynechat obojí současně. Pokud není ke vzorku určena
akce, potom se
vyhovující řádek zkopíruje na výstup. Pro řádek vyhovující více vzorkům bude
akce provedena vícekrát. Řádek nevyhovující žádnému ze zadaných vzorků se
ignoruje.
Pokud vynecháme
vzorek, potom se
akce provede pro
každý načtený řádek. Popis akce se musí uzavřít do složených závorek '
{ }'. Tím se popis akce rozpozná od popisu vzorku.
Záznamy a položky
Vstup, který
awk čte, dělíme do
záznamů (records)
ukončených
oddělovačem záznamu. Implicitním oddělovačem záznamu je
znak nového řádku. V tomto případě je záznamem jeden řádek. Číslo aktuálního
záznamu
awk udržuje v proměnné
NR.
Každý zpracovávaný záznam se dělí do
položek (field). Položky
se implicitně oddělují bílým místem (mezera, tabulátor), lze však explicitně
nastavit jinou hodnotu
oddělovače položek. Na jednotlivé položky
se odkazujeme
$1,
$2 atd. Údaj za znakem dolar je číslo (ne
jenom číslice). Identifikátorem
$0 se odkazujeme na celý záznam.
Počet položek v aktuálním záznamu je uložen v proměnné
NF.
Chceme-li změnit implicitní nastavení oddělovačů záznamů a položek,
nastavíme novou hodnotu do proměnné:
RS pro oddělovač záznamů a
FS pro oddělovač položek. Obsah těchto proměnných můžeme změnit obecně
na regulární výraz (v jiných verzích
awk pouze na libovolný jeden
znak). Oddělovač položek můžeme také nastavit na příkazovém řádku při spouštění
awk volbou
-Fc, kde
c je oddělovač položek.
Je-li oddělovač záznamů prázdný, potom se jako oddělovač chápe
prázdný řádek na vstupu. Oddělovači položek potom jsou znaky mezera, tabulátor
a nový řádek.
V proměnné
FILENAME je uloženo jméno aktuálního vstupního
souboru ('
-' v případě standardního vstupu).
Výstup
Nejjednodušší program, který opíše standardní vstup na standardní
výstup, je následující:
... | awk '{ print }' | ...
Vzorek jsme vynechali, a proto se akce
print provede pro všechny
vstupující řádky. Akce
print bez parametrů opíše celý řádek na výstup.
Užitečnější bude vybrat si určité položky a tyto vypsat, např. první dvě
položky v opačném pořadí:
{ print $2, $1 }
Takový zápis akce na příkazovém řádku spouštějícím
awk musí být
nutně uzavřen do dvojice apostrofů, aby nedošlo k expanzi dvojic znaků
$1 a
$2 na poziční parametry shellu, ale aby se v nezměněné
podobě předaly
awk.
Položky oddělené v zápisu akce
print čárkou se na výstupu
oddělí aktuálně nastavenou hodnotou oddělovače položek. Položky oddělené
pouze mezerou se spojí bez oddělovače. Vyzkoušejme si:
{ print $2 $1 }
Akce
print umí vypisovat i obsahy proměnných a textové
řetězce, např.:
{ print "Číslo záznamu=" NR,
"Počet položek=" NF, $0 }
Takto zadaný program před kompletním záznamem vypíše číslo záznamu a počet
položek v aktuálním záznamu.
Výstup můžeme rozdělit i do více výstupních souborů. Např.
program:
{ print $1 >"soubor1";
print $2 >"soubor2" }
zapíše první položku do souboru
soubor1 a druhou položku do souboru
soubor2. Lze použít i zápis >>. Potom se
do souboru přidává za konec. Jméno souboru může být proměnná, obsah zapisovaný
do souboru může být konstanta. Můžeme tedy napsat např.:
{ print "nesmysl" >>$2 }
Jako jméno souboru se použije obsah druhé položky (pozor, nesmí být prázdná).
V tomto příkladě bude počet řádků v jednotlivých souborech znamenat četnost
slov ve druhém poli.
Podobně lze výstup z akce
print předat rourou
procesu. Např. poslat poštou na adresu 'zaznamenej':
{ print | "mail zaznamenej" }
Pokud si tento příklad vyzkoušíme, zjistíme, že se procesu předá celý
vstup naráz, tj. nepředává se po jednotlivých záznamech a navíc se předá
až po načtení konce vstupu.
Pomocí proměnných
OFS a
ORS můžeme
samostatně nastavit oddělovače pouze pro výstup. Obsahem
OFS se oddělí
vypisované položky a obsahem
ORS se oddělí vypisované záznamy.
Jazyk
awk také poskytuje možnost formátovaných
výstupů pomocí akce
printf. Tato akce se zapisuje následujícím způsobem:
printf formát,výraz
,výraz, ...
Popisovačem
formát sdělíme strukturu výstupu a prostřednictvím
nadefinované struktury vypíšeme jednotlivé
výrazy. V popisovači
formát se používá stejná syntaxe jako v jazyce C. Uveďme si ve stručnosti
možnosti:
Do řetězce
formát vkládáme text, který se
má vypsat. Na místa, kde se má vypsat výsledek výrazu, vložíme popisovač
ve tvaru:
%příznakyšířkapřesnost
typkonverze
Prvnímu popisovači (každý popisovač začíná vždy znakem
%) se přiřadí
výsledek prvního výrazu, druhému popisovači výsledek druhého výrazu atd.
Jednotlivá pole popisovače mají tento význam (všechna pole vyjma
konverze
jsou nepovinná):
[
příznaky]se uvádějí žádný nebo více.
Možné příznaky jsou:
[
-] Výstup bude zarovnán vlevo.
Bez uvedení tohoto příznaku bude výstup zarovnán vpravo.
[
+] Výstup čísla se znaménkem
bude znaménko vždy obsahovat. Bez uvedení tohoto příznaku se uvede pouze případné
záporné znaménko.
[
mezera] Stejné jako příznak
+, jenom se místo kladného znaménka vytiskne mezera. Pokud se uvede
+ i mezera, potom
+ vyhraje.
[
#] Výstup se převede do alternativní
podoby. Podrobnosti jsou uvedeny u popisu každé konverze.
[
šířka] Význam pole záleží na typu
použité konverze.
[
přesnost] Přesnost uvádí, kolik číslic
se má vypsat vpravo od desetinné tečky. Číslu odpovídající přesnosti musí
předcházet tečka. Pokud se uvede tečka bez čísla, použije se hodnota 0.
Přesnost lze zadat pouze s konverzemi
e,
E,
f,
g
a
G.
[
typ] Pole může obsahovat znaky
h ,
l nebo
L. Symbol
h sděluje, že se argument
před výstupem převede na formát
short, typ
l převede na formát
long int a typ
L na formát
long double.
[
konverze] Konverze obsahuje jeden
znak, který sděluje, jak se má
výraz vytisknout.
Na místě
konverze se smějí použít tyto
symboly:
[
i nebo
d]
Předpokládá se celočíselný argument (
int), který se interpretuje
jako číslo se znaménkem. Pole
šířka může obsahovat minimální počet
znaků, na který se číslo vypíše. Implicitně je šířka 1. Význam příznaku
# není definován.
o | Celočíselný argument bez znaménka
se vytiskne osmičkově. Význam pole šířka je stejný jako u konverze |
i. Příznak # zvýší šířku tak,aby první číslice byla nula.
u | Celočíselný argument bez znaménka
se vytiskne desítkově. Význam pole šířka je stejný jako u konverze |
i. Význam příznaku # není definován.
x | Celočíselný argument bez znaménka
se vytiskne šestnáctkově. Na místě číslic se použijí i znaky abcdef
. Význam pole šířka je stejný jako u konverze i. Příznak
# zvýší šířku tak, aby první číslice byla nula. |
X | Celočíselný argument bez znaménka
se vytiskne šestnáctkově. Na místě číslic se použijí i znaky ABCDEF
. Význam pole šířka je stejný jako u konverze i. Příznak
# zvýší šířku tak, aby první číslice byla nula. |
f | Argument ve dvojnásobné přesnosti double se převede do tvaru '[-
]ddd.ddd'. Pole šířka uvádí minimální počet
vytisknutých znaků. Pole přesnost může za tečkou specifikovat počet
desetinných míst. Po uvedení příznaku # se vypíše desetinná tečka,
i když nenásleduje žádná desetinná číslice. |
e | Argument ve dvojnásobné přesnosti
double se převede do tvaru '[-
]d.dddedd'. Exponent budou vždy
alespoň dvě číslice. Zobrazuje-li se hodnota 0, potom je i exponent nulový.
Význam pole přesnost a příznaku # je stejný jako u konverze
f . |
E | Stejné jako e s tím rozdílem,
že se místo e vypíše E. |
g | Stejné jako f nebo e
. Konverze e se použije tehdy, pokud exponent je menší než -4 nebo
je větší než přesnost. |
G | Stejné jako g s tím rozdílem,
že se místo e vypíše E. |
c | Celočíselný argument se převede
na typ unsigned char a výsledný znak se vypíše (tj. ordinální hodnotu
převede na ASCII znak). Význam pole přesnost a příznaku #
je nedefinován. |
s | Předpokládá se, že argumentem je
řetězec znaků (char *). Vypíší se znaky řetězce až po (ale bez) ukončovacího
null znaku. Pole šířka představuje
maximální počet znaků, které se vypíší. Význam příznaku # je nedefinován. |
Akce
printf negeneruje žádné výstupní
oddělovače. Všechny se musejí specifikovat ve
formátu. Uveďme si
příklad použití:
{ printf "Průměr=%8.2f, počet
pokusů=%10ld\n", $1, $2 }
První položka se vytiskne jako číslo v pohyblivé řádové čárce celkem na
8 znaků se dvěma číslicemi za desetinnou tečkou. Druhá položka se vytiskne
jako long integer na 10 znaků. Znak \
n představuje nový řádek.
BEGIN a END
BEGIN a
END jsou speciálními případy
vzorků. Vzorek
BEGIN specifikuje akci, která se má provést dříve,
než se přečte první záznam vstupu. Naopak vzorek
END popisuje akci,
která se provede po zpracování posledního čteného záznamu. Tímto způsobem
můžeme řídit zpracování před a po čtení záznamů.
Jako příklad uveďme nastavení specifického
oddělovače položek a vytisknutí počtu načtených záznamů:
BEGIN { FS = ":" }
...zbytek programu...
END { print NR }
BEGIN musí být jako první vzorek (je-li
uveden),
END musí být posledním vzorkem.
Akce
Akce programu
awk je posloupnost
příkazů vzájemně oddělených novým řádkem nebo středníkem.
Proměnné, výrazy a přiřazení
Jazyk
awk proměnné zpracovává podle
kontextu: buď jako numerické hodnoty (v pohyblivé řádové čárce), nebo jako
řetězce znaků. Řetězce se na numerické hodnoty převádějí podle potřeby. Potom
např.
x = 1
je typicky numerický přiřazovací příkaz, ale v příkazu
x = "3" + "4"
se řetězce převedou na numerické hodnoty a proměnné
x se přiřadí
numerická hodnota 7. Řetězce, ze kterých nelze získat numerickou hodnotu,
mají hodnotu 0.
Proměnná, které dříve nebyla přiřazena
hodnota, má hodnotu nula. Interním proměnným
awk se přiřazují hodnoty
automaticky (viz dále). Proto např. program
{ s1 += $1; s2 += $2 }
END { print s1, s2 }
může k proměnné
s1 přičítat. Proměnná interpretující se jako
řetězec bez přiřazené hodnoty obsahuje prázdný řetězec.
Potřebujeme-li se ujistit, že proměnná
bude chápána jako numerická, přičteme k ní hodnotu 0. Potřebujeme-li naopak
proměnnou interpretovat jako řetězec, připojme k ní prázdný řetězec, např.
b = 12 ""
I když se numerické proměnné zpracovávají
a ukládají v pohyblivé řádové čárce, desetinná tečka a číslice za ní se
vypisují jenom tehdy, pokud je desetinná část nenulová. Číslo se na řetězec
konvertuje podle obsahu proměnné CONVFMT voláním
sprintf. Řetězec
se na číslo konvertuje voláním
atof.
Příklad
Na závěr první části pojednání o
awk uveďme ilustrační příklad:
Chceme
awk použít na převod výstupu
příkazu
ls -l do klasického
DOSovského tvaru výpisu adresáře, tj. ze tvaru:
celkem 692
-rw-r--r-- 1 root root 6608 srp 17 22:04 bind_view.html
-rw-r--r-- 1 root root 3016 srp 17 22:11 bind_view2.html
-rw-r--r-- 1 root root 690798 srp 17 21:45 Bind_9.pdf
do tvaru bind_view.html 6608 srp 17 22:04
Sestavíme-li kolonu (rouru,pípu):
ls -l | grep -v ^total | awk -f dirp
potom pro
awk potřebujeme následující program v souboru
dirp:
BEGIN {print "User is " ENVIRON["LOGNAME"]; print }
{printf "%-18s %10i %3s %2i %4s\n", $9, $5, $6, $7, $8;
suma = suma + $5 }
END {printf " %4i file(s)%11i bytes\n", NR, suma }
Příkazem grep -v ^total zrušíme nevýznamný
řádek začínající slovem
total. Pole
ENVIRON popíšeme v
následující části.
Regulární výrazy
Na místě vzorku se mohou vyskytnout
jak základní regulární výrazy (RE) podle definice v příkazu
ed, tak
i rozšířené regulární výrazy podle definice v příkazu
grep -E. Regulární
výraz se uzavírá do dvojice lomítek. Např. program
/L.*x/
vypíše všechny řádky, které obsahují nejprve znak
L a potom
x. Hledání vyhovujícího vzorku můžeme omezit např. na určitou položku.
Např. program
$1 ~ /^[Ll].*x$/
vypíše ty řádky, jejichž první položka začíná písmenem
L nebo
l a končí písmenem
x. Operátor !~ vybere ten řádek, který vyhovující vzorek neobsahuje.
Relační výrazy
Jazyk
awk povoluje použití relačních operátorů <, >, ==, != , >= a <=.
Např. program
$2 > $1 + 99
vypíše ty řádky, jejichž druhá položka je alespoň o 100 větší než položka
první. Aritmetické operátory se používají stejné jako v aritmetických expanzích
shellu. Např. program
NF % 2 == 0
vypíše všechny řádky se sudým počtem položek. Relační operátory se mohou
používat jak pro aritmetické srovnávání, tak i pro porovnávání řetězců.
Proto např. program
$1 >= "s"
vybere ty řádky, jejichž první položka začíná znakem
s,
t
,
u atd.
Kombinace vzorků
Na místě vzorku se může
vyskytnout i jejich kombinace spojená booleovskými operátory && (AND
- logický součin), || (OR - logický součet) a ! (NOT - negace). Proto např.
vzorek
$1 >= "l" &&
$1 < "o" && $1 !~ /^l.*x$/
způsobí výpis řádku, jehož první položka začíná písmenem
l až
n a zároveň položka
nezačíná
l a zároveň nekončí
x . Operátory && a
|| se vyhodnocují zleva doprava. Vyhodnocování se zastaví v okamžiku, kdy
je výsledek vzorku jasný.
Interval určený vzorky
Vzorek, kterým se vybírá
akce, se může skládat ze dvou vzorků. Potom levý vzorek určuje první řádek
a pravý vzorek určuje poslední řádek, pro který se akce provede. Např. vzorek
/start/,/stop/
vypíše všechny řádky od řádku vyhovujícího vzorku /start/ po řádek vyhovující
vzorku /stop/. Např. program
NR == 100,
NR == 200
vypíše záznamy (řádky) 100 až 200.
Identifikátor položky jako proměnná
Identifikátory položek
(
$1, ...) požívají stejných vlastností jako proměnné. Mohou se používat
jak v aritmetickém, tak i řetězcovém kontextu. Lze jim také přiřadit hodnotu.
Proto lze napsat např.
{ $2 = NR;
print }
nebo dokonce
{ $1 =
$2 + $3; print $0 }
Odkazy na konkrétní
položky se mohou také vyjádřit numerickým výrazem, např.
{ print
$i, $(i+1), $(i+n) }
Příkazy pro řízení toku
Jazyk
awk
dovoluje použít příkazy pro řízení toku obvyklé u vyšších programovacích
jazyků. Jde o tyto příkazové konstrukce:
if (podmínka) příkaz [ elsepříkaz
]
while (
podmínka) příkaz
do
příkazwhile (podmínka)
for (
výraz1; výraz2; výraz3) příkaz
for (
proměnnáinpole) příkaz
break
continue
next
delete
pole[index]
exit
[ výraz
]
{příkaz
[; příkaz ... ] }
Z výše uvedených konstrukcí můžeme vytvořit např. tyto příklady:
{ if ($3 > 1000)
$3 = "moc velké"
print
}
Následující příklad vytiskne vždy jednu položku na jeden řádek:
{ i = 1
while (i <= NF) {
print $i
++i
}}
V příkladu jsme si ukázali, že na místě
příkazu smí být i více příkazů
uzavřených do složených závorek. Následující příkaz provede totéž:
{ for (i = 1; i <= NF; i++) print $i }
První výraz znamená počáteční přiřazení, druhý výraz představuje podmínku
a třetí výraz se opakovaně provádí.
Příkaz
break
okamžitě ukončí provádění cyklu
while nebo
for. Příkaz
continue přejde ihned na novou iteraci cyklu.
Příkazem
next
přejdeme na zpracování dalšího řádku (záznamu) vstupu. Příkaz
exit
je totéž, co načtení konce vstupu (souboru).
Do programu
pro
awk lze vkládat komentáře. Řádek s poznámkou musí začínat znakem
#.
Pole
Pole (arrays) se v
awk předem nedeklarují. Jako příklad použití pole uveďme
{ x[NR] = $0 }
Tímto programem načteme celý vstup do jednorozměrného pole a zpracujeme
jej až v akci náležející speciálnímu vzorku
END.
Prvky
pole můžeme indexovat také nenumerickými hodnotami, např. řetězci. Ukažme
si opět příklad použití
/modra/ { x["modra"]++ }
/cervena/ { x["cervena"]++ }
END { print x["modra"],
x["cervena"] }
Pole v
awk mohou být obecně
n-rozměrná. Jejich prvky se totiž
ukládají tak, jak je tomu u asociativních pamětí. S prvkem je uložen i jeho
index. V případě více prvkových položek se jednotlivé indexy od sebe oddělují
oddělovačem (tuto hodnotu lze změnit proměnnou SUBSEP, viz dále). Potom
např.
i = "A"; j = "B"; k = "C"
x[i,j,k] = "hello, world\n"
do paměti uloží index ve tvaru A\034B\034C. V příkazu
for můžeme
použít zvláštní operátor
in následovně:
for (proměnná in pole) ...
Operátor
in v příkazu
for zajistí, že
proměnné se
budou postupně přiřazovat všechny prvky
pole. Prvky jsou přiřazovány
obecně v náhodném pořadí. Pokud obsah
proměnné změníme nebo pokud
současně zpřístupňujeme i jiné prvky pole, nastane zřejmě chaos. Je-li pole
vícerozměrné, můžeme pro uložení všech indexů (jako řetězce) použít jednu
proměnnou.
Operátor
in můžeme použít i v příkazech
if a
while
ke zjištění, zda element určitého indexu se v poli nachází. Můžeme napsat
if (hodnota in pole) print pole[hodnota]
V případě vícerozměrných položek používáme zápis např.
if (("A","B","C") in x)
print x["A","B","C"]
Prvky pole rušíme příkazem
delete např. následovně:
delete x["A","B","C"]
Funkce
Funkce nebyly do původního
awk zahrnuty. Definují se tímto způsobem:
function jméno(seznam_parametrů) {příkazy
}
Při volání funkce se formální parametry nahradí aktuálními. Pole se předávají
odkazem, ostatní proměnné hodnotou.
Lokální proměnné se ve funkcích definují dost zvláštním způsobem. Je to
zapříčiněno faktem, že původní
awk pojem lokální proměnné nezná. Lokální
proměnné se definují v rámci
seznamu_parametrů tak, že se uvedou na
konci a oddělí se více mezerami, např.:
function f(p, q, a, b)
{ # proměnné a, b jsou lokální
... }
/abc/ { ... ; f(1, 2); ... }
Levá kulatá závorka musí následovat bezprostředně za jménem funkce (bez
bílého místa). Tím se odstraní případné nejednoznačnosti syntaxe (možnost
záměny s konkatenací).
Z funkce se smí volat jiná funkce a funkce smějí být rekurzivní. Na místě
slova
function se smí použít jenom
func (rozšíření GNU verze).
Interní proměnné awk
[
ARGC]Obsahuje počet argumentů zadaných na příkazovém
řádku při spouštění
awk. Volby se do argumentů nepočítají.
ARGIND | Index do ARGV na právě zpracovávaný
soubor. |
ARGV | Pole argumentů z příkazového řádku. Pole
se indexuje od 0 do ARGC-1. Obsah tohoto pole můžeme měnit a tím řídíme výběr
souborů ke zpracování. |
CONVFMT | Formát pro konverzi čísel, implicitně
'%.6g'. |
ENVIRON | ]Pole obsahující kopii proměnných prostředí.
Indexem je jméno proměnné; vyzkoušejte např. ENVIRON["HOME"]. Obsah
jednotlivých prvků pole můžete měnit. Tato změna se však neprojeví na proměnných
prostředí předávaných procesům, které jsou z awk spouštěny (např.
symbolem |). Tato vlastnost se může v dalších verzích změnit. |
ERRNO | Tato proměnná obsahuje řetězec popisující
chybu, která vznikla během poslední operace getline, přesměrování a zavření. |
FILENAME | Jméno právě zpracovávaného souboru nebo
'-' pro standardní vstup. Proměnná FILENAME je uvnitř bloku BEGIN
nedefinována. |
FNR | Číslo vstupního záznamu v rámci aktuálního
souboru. |
FS | Oddělovač položek na vstupu; implicitně mezera. |
IGNORECASE | Proměnná řídí zpracování malých a velkých
písmen ve všech operacích s regulárními výrazy. Obsahuje-li proměnná IGNORECASE
nenulovou hodnotu, potom se ignorují rozdíly mezi malými a velkými písmeny.
Implicitně proměnná obsahuje nulu. |
NF | Počet položek aktuálně zpracovávaného záznamu. |
NR | Počet načtených záznamů. |
OFMT | Výstupní formát čísel, implicitně '%.6g
'. |
OFS | Oddělovač položek na výstupu; implicitně mezera. |
ORS | Oddělovač záznamů na výstupu; implicitně nový
řádek. |
RS | Oddělovač záznamů na vstupu; implicitně nový
řádek. Z řetězce RS se akceptuje pouze první znak (což se může v budoucích
verzích změnit). Pokud RS obsahuje prázdný řetězec, potom se záznamy oddělují
prázdným řádkem a položky novým řádkem bez ohledu na nastavení FS. |
RSTART | Index prvního vyhovujícího znaku vraceného
funkcí match(). Pokud žádný nevyhovuje, potom proměnná obsahuje 0. |
RLENGTH | Délka vyhovujícího řetězce vraceného
funkcí match(). Pokud žádný nevyhovuje, potom proměnná obsahuje -1. |
SUBSEP | Znak oddělující jednotlivé indexy při ukládání
indexu prvku vícerozměrného pole. Implicitně \034. |
Vstupní a výstupní funkce
Následuje souhrnný přehled dosud uvedených i neuvedených vstupních a výstupních
funkcí:
close(soubor) | Zavře soubor (nebo přesměrování). |
getline | Načte další záznam do $0, nastaví se NF, NR, FNR. |
getline <soubor | Načte další záznam do $0ze souboru soubor, nastaví se NF, NR, FNR. |
getlinevar | Načte další záznam do var, nastaví se NF, NR, FNR. |
getlinevar <soubor | Načte další záznam do var ze souboru soubor, nastaví se NF, NR, FNR. |
next | Ukončí se zpracovávání běžného záznamu (řádku). Přečte se další záznam a
zahájí se provádění prvního příkazu programu. Pokud se načte konec souboru,
provede se blok END (je-li nějaký). |
next file | Ukončí se zpracovávání aktuálně čteného souboru. Další řádek se čte už z
dalšího souboru. Obnoví se FILENAME, FNR se nastaví na 1. Přečte se další
řádek a zahájí se provádění prvního příkazu programu. Pokud se načte konec
souboru, provede se blok END (je-li nějaký). |
print | Vytiskne běžný záznam. |
printseznam_výrazů | Vytiskne uvedený seznam výrazů. |
printseznam_výrazů >soubor | Vytiskne uvedený seznam výrazů do souboru. |
printfformát, seznam_výrazů | Vytiskne uvedený seznam výrazů podle zadaného formátu. |
printfformát, seznam_výrazů >soubor | Vytiskne uvedený seznam výrazů podle zadaného formátu do souboru. |
system(příkaz_systému) | Shell provede zadaný příkaz_systému a převezme se návratový kód. |
Numerické funkce
V
awk můžeme používat následující vestavěné aritmetické funkce.
atan2(y, x) | Vypočte arkustangens y/x a vrátí hodnotu v radiánech. |
cos(výraz) | Vrátí kosinus výrazu v radiánech. |
exp(výraz) | Exponenciální funkce. |
int(výraz) | Odřízne desetinnou část. |
log(výraz) | Přirozený logaritmus. |
rand() | Náhodné číslo mezi 0 a 1. |
sin(výraz) | Sinus. |
sqrt(výraz) | Druhá odmocnina. |
srand(výraz) | Zadaný výraz se použije na "rozmíchání" generátoru náhodných čísel.
Není-li výraz uveden, potom se použije aktuální hodnota času. Funkce
vrátí předchozí hodnotu výrazu. |
Řetězcové funkce
asort(s [, d]) |
Vrátí počet prvků ve zdrojovém poli s. Obsah s je setříděn
za použití standardních pravidel gawk-u pro porovnávání hodnot, a
indexy setříděných hodnot sorted values pole s jsou nahraženy posloupností
celých čísel počínaje od 1. Jestliže je specifikováno volitelné cílové pole
d, pak je nejdříve s zkopírováno do d, pak je d
setříděno, a indexy zdrojového pole s jsou nezměněny. |
gensub(r, s, h [, t]) |
Prohledává řetězec t na splnění regulárního výrazu r. Pokud
h je řetězec začínající g nebo G, pak nahradí všechny shody
r řetězcem s. Jinak h je číslo udávající kolikátá shoda
r se má nahradit. Pokud t není uvedeno,je místo něho použita proměnná
$0. Posloupnost \n uvnitř nahrazujícího textu s,
kde n je číslice od 1 do 9, může být užita k indikaci právě jen textu,
který splňuje n-tý závorkovaný podvýraz. Posloupnost \0 zastupuje
celý splňující text, stejně jako znak &. Na rozdíl od sub()
a gsub() je jako výsledek vrácen modifikovaný řetězec a původní
řetězec je nezměněn. |
gsub(r, s, t) |
Každý podřetězec řetězce t vyhovující regulárnímu výrazu r se
nahradí řetězcem s. Funkce vrací počet náhrad. Pokud nebyl zadán řetězec
t, použije se $0. |
index(s, t) |
Vrátí index podřetězce t v rámci řetězce s nebo 0, pokud se podřetězec nenašel. |
length(s) |
Funkce vrátí délku řetězce s nebo řetězce $0, pokud jsme s nezadali. |
match(s, r) |
Vrátí se pozice uvnitř řetězce s, od které začíná podřetězec vyhovující
RE r. Nenajde-li se, vrátí se 0. Funkce rovněž nastavuje proměnné RSTART a RLENGTH. |
split(s, a, r<) |
Rozdělí řetězec s do jednorozměrného pole a podle RE r
. Pokud r nezadáme, použije se obsah FS. Funkce v řetězci najde všechny
výskyty oddělovače podle r. Tyto výskyty rozdělí řetězec na podřetězce
a jednotlivé podřetězce se uloží do elementů pole a číslovaných od
1. Funkce vrátí počet podřetězců. |
sprintf(formát, výrazy) |
Funkce vytiskne výrazy podle zadaného formátu. Vrátí se výsledný řetězec. |
strtonum(str) |
Testuje str a vrací jeho numerickou hodnotu. Pokud str začíná
úvodní 0, strtonum() předpokládá že str je osmičkové
číslo. Pokud str začíná úvodní 0x nebo 0X, strtonum()
předpokládá, že str je hexadecimální číslo. |
sub(r, s, t) |
Funkce se od gsub() liší tím, že se nahradí pouze první vyhovující řetězec. |
substr(s, i, n) |
Funkce vrací n-znakový podřetězec řetězce s začínající na pozici
i. Pokud n vynecháme, vezme se zbytek řetězce s. |
tolower(řetězec) |
Vrací se řetězec se všemi velkými písmeny převedenými na malá písmena.
Jiné znaky než velká písmena zůstanou beze změny. |
toupper(řetězec) | Vrací se řetězec se
všemi malými písmeny převedenými na velká písmena. Jiné znaky než malá písmena
zůstanou beze změny. |
Časové funkce
Program GNU
awk poskytuje možnost doplňovat produkovaný text informací
o datu a čase.
-
mktime(datespec)
-
Konvertuje datespec do časového razítka (time stamp = počet vteřin
od 1.1.1970) ve stejném tvaru jako vrací systime(). datespec
je řetězec tvaru YYYY MM DD HH MM SS[ DST]. Obsahem řetězce je šest
nebo sedm čísel reprezentujících úplný rok včetně století, měsíc od 1 do
12, den v měsíci od 1 do 31, hodinu dne od 0 do 23, minutu od 0 do 59, a
vteřinu od 0 to 60, a volitelný příznak letního času. Hodnoty těchto čísel
nemusí být uvnitř specifikovaného rozsahu; např. hodina zapsaná jako -1 znamená
1 hodinu před půlnocí. Je předpokládán Gregoriánský kalendář s počátkem v
nule, kde rok 0 předchází roku 1 a rok -1 předchází roku 0. Čas je předpokládán
v místní časové zóně. Pokud je příznak letního času kladný, předpokládá se
letní čas; pokud je nula, předpokládá se stndardní čas; a pokud je záporný
(defaultní), mktime() se pokouší zjistit zda je zadaný čas v letním
čase. Pokud datespec neobsahuje dostatek elementů nebo je výsledný
čas mimo rozsah, mktime() vrací hodnotu -1.
-
systime()
-
Funkce předává aktuální čas v počtu sekund od 1.1.1970 (v POSIX kompatibilních
systémech).
-
strftime(formát, čas)
-
Funkce zformátuje údaj čas podle zadaného formátu. Hodnota
čas musí být v takovém tvaru, jaký produkuje systime()
. Pokud hodnotu čas vynecháme, uplatní se aktuální čas. Řetězec
formát se zadává stejně jako ve stejnojmenném knihovním podprogramu.
Řetězec
formát funkce
strftime() obsahuje jak identifikaci
časových údajů (začínají znakem
%), tak i normální text - ten se opíše
beze změn. Časové údaje jsou následující (uživatel by měl mít možnost konfigurovat
údaje předávané touto funkcí podle národních zvyklostí):
%a | Zkratka dne v týdnu. |
%A | Plné jméno dne v týdnu. |
%b | Zkratka názvu měsíce. |
%B | Plný název měsíce. |
%c | Preferovaný způsob zápisu data a času. |
%d | Den v měsíci (desítkově). |
%H | Hodina ve 24hodinovém cyklu (00 až 23). |
%I | Hodina ve 12hodinovém cyklu (01 až 12). |
%j | Den v roce (001 až 366). |
%m | Měsíc (01 až 12). |
%M | Minuta desítkově. |
%p | AM nebo PM. |
%S | Sekunda. |
%U | Týden v roce (desítkově). První týden začíná první nedělí v roce. |
%W | Týden v roce (desítkově). První týden začíná prvním pondělím v roce. |
%w | Den v týdnu (desítkově). Neděle je den 0. |
%x | Preferovaný způsob zápisu data bez času. |
%X | Preferovaný způsob zápisu času bez data. |
%y | Rok bez století (00 až 99). |
%Y | Rok včetně století. |
%Z | Jméno nebo zkratka časové zóny. |
%% | Znak procento. |
Uveďme si příklad:
strftime("Dnes je %d. %m. %Y
a máme %H:%M hodin.")
Řetězcové konstanty
Řetězcové konstanty uvnitř programu pro
awk jsou řetězce uzavřené
do dvojic uvozovek. Uvnitř těchto řetězcových konstant můžeme používat tyto
escape posloupnosti:
\\ | Znak obrácené lomítko. |
\a | Znak 'zvonek' - pípne (alert). |
\b | Backspace - návrat o znak zpět. |
\f | Nová stránka (form feed). |
\n | Nový řádek (new line). |
\r | Návrat vozíku (carriage return). |
\t | Horizontální tabulátor. |
\v | Vertikální tabulátor. |
\x | hex Znak zapsaný šestnáctkově, např. \x1B je znak ESCAPE. |
\oct | Znak zapsaný osmičkově, např. \033 je znak ESCAPE. |
\c | Literál znaku c. |
Výše uvedené escape posloupnosti se mohou použít i uvnitř jednoznakového
RE reprezentujícího třídu znaků. Např. '/[ \t\f\n\r\v]/' vyhovuje všem znakům
typu "bílé místo".
Speciální soubory
GNU verze
awk při přesměrovávání výstupu příkazů print, printf a
při čtení pomocí getline interně zpracovává následující speciální soubory.
Tyto speciální soubory zprostředkují přístup k otevřeným popisovačům souborů
zděděných od rodiče (zpravidla od shellu) nebo poskytnou informace o procesu.
/dev/pid | - Přečtením tohoto souboru obdržíme číslo aktuálně běžícího procesu ukončené
znakem nového řádku. |
/dev/ppid | - Přečtením tohoto souboru obdržíme číslo rodičovského procesu. |
/dev/pgrpid | - Přečtením tohoto souboru získáme skupinové ID aktuálně běžícího procesu. |
/dev/user | - Přečtením tohoto souboru obdržíme jeden záznam ukončený novým řádkem. Položky
záznamu jsou odděleny mezerou. Položka $1 obsahuje uživatelské ID z volání
getuid(), $2 obsahuje uživatelské ID z volání geteuid(), $3 obsahuje ID skupiny
z getgid(), $4 je hodnota z getegid(). Případné další položky jsou hodnoty
vrácené voláním getgroups(). Tato jména souborů jsou nyní zastaralá.
Užijte pole PROCINFO k získání těchto informací. |
/dev/stdin | - Standardní vstup. |
/dev/stdout | - Standardní výstup. |
/dev/stderr | - Standardní chybový výstup. |
/dev/fd/ n | - Soubor spojený s otevřeným popisovačem souboru číslo n. |
Výstup na standardní chybový výstup můžeme poslat např. tímto příkazem:
print "Stala se chyba!" > "/dev/stderr"
Následující speciální jména souborů mohou být užita s
|& ko-proces
operátorem pro vytvoření TCP/IP síťových spojení.
/inet/tcp/lport/rhost/rport
- Soubor pro TCP/IP spojení z lokálního portu
lport na vzdálený počítač
rhost na vzdálený port
rport. Užijte port
0 k jeho automatickému
výběru systémem.
/inet/udp/lport/rhost/rport -
Podobné, ale užívá UDP/IP místo TCP/IP.
/inet/raw/lport/rhost/rport -
Rezervováno pro budoucí použití.
Volby GNU awk
Identifikátory voleb podle POSIX začínají jedním znakem minus, volby podle
GNU začínají dvěma minusy. V rámci jedné volby
-W lze zadat více slovních
voleb, stejně tak lze zadat i více voleb
-W na jednom řádku.
-
-F fs nebo --field-separator=fs
Nastavení oddělovače položek na vstupu (tj. určení implicitní hodnoty proměnné
FS).
-
-v proměnná=hodnota nebo
- --assign=proměnná=hodnota
Uvedené proměnné se přiřadí zadaná hodnota. Takto nastavené proměnné jsou
k dispozici již během bloku BEGIN.
-
-f soubor nebo --file=soubor
Program se bude číst ze zadaného souboru. Těchto voleb může být na příkazovém
řádku více.
-
-W compat nebo --compat
Program GNU awk se spustí v režimu kompatibility s klasickým awk
. Všechna GNU rozšíření jsou vypnuta.
-
-W copyleft nebo -W copyright nebo --copyleft
nebo --copyright
Na standardní chybový výstup se vypíše GNU copyright.
-
-W help nebo -W usage nebo --help nebo
--usage
Na standardní chybový výstup se vypíše krátká nápověda k programu.
-
-W lint nebo --lint
Program upozorní na ty programové konstrukce, které nemusejí jiné implementace
awk zpracovat.
-
-W posix nebo --posix
Zapne se kompatibilní režim s následujícími omezeními:
- sep=0mm
- Nerozpoznají se escape posloupnosti \x.
- Nerozpozná se synonymum func pro function.
- Na místo operátorů ^ a ^= se nesmějí použít operátory ** a **=.
-
-W source=program nebo --source=program
Jako argument této volby se zadává text programu pro awk. Význam
spočívá v možnosti číst v rámci jednoho spuštění awk program jak ze
souboru (např. knihovnu funkcí), tak i z příkazového řádku (vlastní krátký
program). V tomto případě nelze v rámci volby -W zadat volbu další.
-
-W version nebo --version
Na standardní chybový výstup předá informaci o verzi aktuálního awk
.
-
-- Oznamuje konec zadávání voleb.
Proměnná AWKPATH
Do proměnné prostředí AWKPATH můžeme obvyklým způsobem nastavit seznam
cest k adresářům, které se budou procházet při hledání programů (tj. uvedených
za volbou
-f). Pokud proměnná neexistuje, použije se implicitní hodnota:
.:/usr/lib/awk:/usr/local/lib/awk
GNU awk rozšíření
Na závěr shrneme rozšíření GNU verze
awk oproti definici POSIX
(viz též volba
-W compat):
Escape posloupnosti \
x
Funkce systime() a strftime()
Rozpoznávání jmen zvláštních souborů
Proměnné ARGIND, ERRNO, AWKPATH a IGNORECASE
Příkaz 'next file'
Ilustrační příklady
Příklad 1:
Mějme textovou databázi předmětů, ze kterých si student při zápisu do semestru
vybírá. Jednotlivé položky oddělujeme dvojtečkou. Učitel je v databázi jednoznačně
identifikován svým přihlašovacím jménem. Pokud je více než jeden učitel, pak
jsou jejich přihlašovací jména oddělena čárkou. Databáze nechť má tento tvar:
P000:3:zk:Architektura počítačů:brandejs
P004:2:zk:UNIX:brandejs
I011:2:zk:Sémantiky programovacích jazyků:
zlatuška
Úkol zní: vypsat obsah databáze v "čitelném" tvaru a převést přihlašovací
jméno na příjmení a první písmeno křestního jména. Pro tento účel si vytvořme
např. soubor
logins s následujícím obsahem:
adelton:Jan:Pazdziora
brandejs:Michal:Brandejs
kas:Jan:Kasprzak
kron:David:Košťál
zlatuska:Jiří:Zlatuška
Pro převod přihlašovacího jména na příjmení pak použijeme jednorozměrné
pole, kde indexem bude přihlašovací jméno a obsahem zkonstruovaná dvojice
příjmení a křestního jména. Pole naplňujeme pouze jednou, a to v části BEGIN.
Databáze předmětů nechť se načítá ze standardního vstupu.
... | awk -F':' 'BEGIN { while ( getline
<"logins" == 1 ) {
logins[$1]=sprintf("%s %1.1s.", $3, $2) } }
{ pocet=split($5,loginy,",")
for (i=1; i <= pocet; i++) {if (i == 1)
last = logins[loginy[i]]
else last = last ", " logins[loginy[i]]; }
printf("%-5s %-50.50s %1s %2s %s\n",$1,$4,
$2,$3,last) }'
Příklad 2:
Následujícím programem spočítáme počet všech různých slov v textu:
BEGIN { FS="[^a-zA-Z]" }
{ for (i=1;i<=NF;i++) words[$i] = "" }
END { delete words[""]
# prázdné položky nepočítáme
for (i in words) sum++
print "V textu bylo " sum " různých
slov"
}
Příklad 3:
A poslední vzorový program vykonává totéž co příkaz
wc:
{words+=NF; chars+=1+length($0)}
END {print NR,words,chars}