Programování v unixovém shellu – úkoly
Seminář 1
Úkoly z cvičení 2 až 7 v předmětu Unixové systémy.
Seminář 2
Úkoly z cvičení 8 až 12 v předmětu Unixové systémy.
Seminář 3
Úkol 1:
Vytvořte skript, který vypíše seznam všech souborů a podadresářů v adresáři (= obsah
adresáře), zadaném jako argument skriptu, s informacemi o typu (-
=
soubor, d
= adresář, l
= symbolický odkaz) a právech (r
=
čtení, w
= zápis, x
= spouštění) pro spouštějícího uživatele,
ve tvaru: jméno typ práva, např. pokus d rwx
. Při
žádném argumentu skriptu v aktuálním
adresáři, při prvním argumentu -a
(adresář by byl
druhý argument) včetně
tzv. skrytých souborů a podadresářů (jinak bez nich, skryté
jsou i .
a ..
). Řešte bez
použití programů ls a dir!
Použití: ./ls [-a] [adresar]
[2 body]
Úkol 2:
Naprogramujte, jako skript, hádání
(celého) čísla, které si uživatel
myslí a skript vypíše, z intervalu zadaného až dvěma argumenty skriptu, sérií (pouze!)
dotazů
je menší/větší než X?
s odpověďmi a/n algoritmem půlení intervalu. Při
jednom argumentu skriptu je levá mez intervalu 0, při žádném
navíc pravá mez 100.
Použití: ./cislo [[od] do]
[2 body]
Úkol 3:
Implementujte, jako funkci, zjednodušenou verzi programu seq: výpis
posloupnosti (celých) čísel oddělených mezerou od čísla
zadaného jako první argument funkce do čísla zadaného jako třetí
argument, obojí včetně, s přírůstkem zadaným jako druhý
argument – kladným, pokud je počáteční číslo menší nebo rovno
než koncové, jinak záporným. Při dvou argumentech funkce je
chybějící přírůstek roven 1, při jednom argumentu je i chybějící
počáteční číslo rovno 1.
Použití: (. seq.sh; seq [od [prirustek]] do)
[4 body]
Seminář 4
Úkol 4:
Napište funkce vracející (vypisující)
- číslo zadané jako argument funkce v poziční číselné soustavě o základu 2 až 64 (cifry jsou 0-9, a-z, A-Z, @ a _) v desítkové soustavě,
- zápis čísla zadaného jako argument funkce v desítkové soustavě v soustavě o základu 2 až 64 (...).
Použití:
(. doz10.sh; do10 cislo [zaklad]; z10 cislo [zaklad])
[3 body]
Úkol 5:
Implementujte jako funkce (zjednodušené)
programy dirname a basename: z cesty zadané jako
argument funkce, po odebrání
případného /
na konci, vrátí (vypíše) část před
(dirname), resp. za (basename) posledním /
(při
výsledném prázdém řetězci vrátí /
). Pokud
(případně upravená) cesta /
neobsahuje, dirname
vrátí .
(tečku) a basename celé jméno.
Použití: (. dirbasename.sh; dirname cesta; basename cesta)
[2+2 body]
Seminář 5
Úkol 6:
Vytvořte skript, který do
adresáře zadaného jako argument skriptu vygeneruje 1000 souborů z následujícího úkolu s
pořadovými čísly 0001 až 1000 a náhodným datem.
Použití: ./gen adresar
[2 body]
Úkol 7:
Uvažujme adresář obsahující soubory XYZNNNN.jpg
, kde XYZ je nějaká předpona a NNNN je pořadové
číslo od 0000 do 9999. V každém souboru je textově zapsané datum
ve tvaru MM/DD/YYYY (ne nutně reálné, MM
od 01 do 12, DD od 01 do 31, YYYY od 0001 do 9999; ve skutečnosti
by z validních souborů fotek ve formátu JPEG bylo možné získat
datum a čas pořízení fotky
z EXIF informací v souboru). Například adresář v ZIP
archivu (pro rozbalení
spusťte unzip fotky.zip
). Vytvořte skript s
tímto adresářem jako argumentem skriptu, který přesune soubory do
podadresářů tohoto adresáře s cestami ve tvaru YYYY/MM/DD
. Každý podadresář bude
existovat jen pokud v něm bude alespoň jeden soubor.
Použití: ./presun adresar
[5 bodů]
Seminář 6
Úkol 8:
Vytvořte sed skript, který z textu vypíše jen řádky od
10. do 20. řádku včetně (počítáno od 1) v opačném pořadí.
Použití: sed -f rev10-20.sed [soubor-s-textem]
[4 body]
Úkol 9:
Vytvořte sed skript, který sloučí sousední řádky textu
končící znakem -
, pokud před ním nejsou bílé
znaky (mezery a tabulátory) spolu s následujícím
řádkem (již bez znaku -
na konci) do jednoho řádku, s odstraněním znaků -
.
Použití: sed -f slouceni.sed [soubor-s-textem]
[5 bodů]
Seminář 7
Úkol 10:
Vytvořte skript (shell, sed), který pro
každý řádek na vstupu ve tvaru 'Jméno Příjmení
<emailová@adresa>' (bez '', položky oddělené mezerami) vytvoří kopii textového
souboru, šablony zadané jako argument skriptu, ve kterém
budou všechny řetězce JMENO a PRIJMENI nahrazeny Jménem a Příjmením ze
vstupu a před obsahem souboru bude na prvním řádku <emailová@adresa> následovaná prázdným
řádkem. Kopie budou pojmenovány stejně jako šablona, jen s doplněním čísla
řádku ze vstupu ve jménu souboru.
Použití: echo -e 'Jméno Příjmení
<emailová@adresa>\n...' | ./dopisy sablona
[3 body]
Úkol 11:
Vytvořte skript (shell, sed), který z HTML dokumentu
na vstupu nebo v souboru zadaném jako argument skriptu vypíše pouze URL adresy všech odkazů, přesněji hodnoty atributu HREF
všech elementů A
v dokumentu (<A ... HREF="URL">
). Nezapomeňte korektně ošetřit i případy, kdy za jménem
elementu A
mohou být i jiné atributy než HREF
a kdekoliv mezi A
a HREF
může být element rozlomen do více řádků! Rozlomení samotných
URL adres nepředpokládejte.
Použití: ./urls [html-dokument]
[4 body]
Seminář 8
Úkol 12:
Implementujte jako awk program zjednodušenou verzi wc: výpis počtu
znaků (včetně konců řádků), slov (neprázdná posloupnost znaků oddělená mezerami nebo
tabulátory) a řádků v textu.
Použití: awk -f wc.awk [soubor-s-textem]
[3 body]
Úkol 13:
Implementujte jako awk program převrácení tabulkových dat (sloupce
oddělené mezerami nebo tabulátory) v textu podle hlavní diagonály, tj. výměnu řádků a
sloupců.
Použití: awk -f trans.awk [soubor-s-textem]
[3 body]
Seminář 9
Úkol 14:
Vytvořte skript (shell, sed, awk aj.), který pro každého uživatele,
který má aktuálně v systému spuštěný alespoň jeden proces,
vypíše jméno uživatele (login) a celkové množství paměti zabrané všemi těmito jeho aktuálně v
systému spuštěnými procesy. Jako
množství paměti zabrané procesem použijte hodnotu rss
vypisovanou
pro procesy programem ps.
Použití: ./mem
[3 body]
Úkol 15:
Vytvořte skript (shell, sed, awk aj.), který pro počet dní
zadaný jako argument skriptu a každého uživatele, který byl nebo aktuálně stále je v systému
přihlášen za posledních zadaný počet dní, vypíše celkovou dobu přihlášení (sezení) uživatele v
systému do aktuálního času. Jako dobu jednoho přihlášení (sezení) uživatele v
systému použijte hodnotu vypisovanou v posledním sloupci, pro
uživatele v prvním sloupci, programem last spustěným s
argumentem pts/{0..9}
. Tato hodnota má tvar
(počet dní+hodin:minut)
, kde část počet dní+
nemusí být uvedena, nebo je to still logged
in
v případě, že uživatel je aktuálně stále v systému
přihlášen – v tomto případě je v předposledním sloupci
výpisu last
vypsaný čas přihlášení
uživatele. Celkovou dobu přihlášení vypište ve stejném tvaru.
Použití: ./doba pocet-dni
[6 bodů]
Seminář 10
Úkol 16:
Vytvořte skript, který pro seznam jmen ve tvaru Jméno Jméno ... tabulátor PŘÍJMENÍ
PŘÍJMENÍ ... (Jména a PŘÍJMENÍ oddělená mezerami), např. ze souboru,
zapsaný v souboru zadaném jako argument skriptu nebo načtený ze vstupu, vypíše ke každému
Jménu v seznamu, v abecedním pořadí Jmen, počet jmen s tímto Jménem.
Použití: ./jmen [soubor-se-jmeny]
[3 body]
Úkol 17:
Vytvořte skript, který vypíše seznam jmen z předchozího úkolu
(opět ze souboru zadaném jako argument skriptu nebo načteném
ze vstupu) se všemi PŘÍJMENÍ přepsanými na Příjmení.
Použití: ./prijmeni [soubor-se-jmeny]
[4 body]