Třinácté cvičení – Dodělání AWK + větší příklad (domácí)
Navážeme na AWK z minulého cvičení.
Základy AWK:
Zobrazit/skrýt základy AWKDodělání AWK
Lepší matchování
Matchovat se lze i jenom na některý field záznamu a to konstrukcí $1 ~ /.../
.
A vzory lze také kombinovat pomocí &&
a ||
a negovat !
:
$3 ~ /^Volkswagen/ # Matchují záznamy se třetím sloupce začínajícím na "Volkswagen"
$3 !~ /^Volkswagen/ # Všechny ostatní
!/^#/ # Nezakomentované řádky
/^#/ || $3 ~ /^Volkswagen/ # Záznamy buď celé zakomentované, nebo se třetím sloupce začínajícím na "Volkswagen"
Funkce v AWK
function minimum(pole, min) {
min = pole[0]
for (i in pole) {
if (pole[i] < min) min = pole[i]
}
return min
}
Pozor, nedají se v nich definovat lokální proměnné. Ale dá se použít trik s neuvedenými proměnnými v hlavičce – při volání není potřeba uvést
všechny argumenty a AWK za ně dosadí prázdnou hodnotu. Funkci výše lze tedy zavolat klidně jako minimum(pole)
a min
pak
použijeme jenom uvnitř funkce.
Velký úkol
Příklad je zadaný jako úkol v odevzdávacím systémku. Tento úkol je poměrně volný, základ bodování je 10 bodů, ale podle (ne)pěknosti řešení a toho, kolik funkcionality implementujete, můžete dostat až +/- 5 bodů od základu. Snažte se o srozumitelný a rozumný kód, pište komentáře, prostě ať se v tom sami vyznáte.
Napište skript, který dostane URL a stáhne z ní a z odkazovaných
stránek všechny emailové adresy. Měl by umět nastavit hloubku rekurze pomocí
parametru -r <číslo>
, defaultně 10.
Měl by umět:
- Rekurzivní stahování – nalezne na stránce odkazy na jiné stránky a na nich zkusí rekurzivně opět najít emailové adresy (a tak dál až do hloubky rekurze)
- Zajistit, aby se stejná stránka nestahovala vícekrát (aby nevznikaly třeba nekonečné cykly stahování)
- Stahovat jenom z domény, na jaké bylo původní URL (tedy aby to při stahování z http://kam.mff.cuni.cz/~setnicka/ neprocházelo třeba Wikipedii)
Nápověda: Zajistit stahování každé stránky jenom jednou lze třeba pomocí seznamu již stažených stránek, nebo třeba vytvářením souboru pro každou staženou stránku. Nebo třeba úplně jinak :-)
Rady pro jednotlivé části:
- Parsování argumentů – pomocí příkazu
getopts
- Formátovací string:
ab:c
definuje přepínačea
,b
ac
, kdeb
bere parametr getopts
vrací postupně všechny parametry (název v definované proměnné, hodnotu v$OPTARG
a číslo parametru v$OPTIND
)- Pro zpracování jednotlivých parametrů se hodí použít
case <proměnná> in
, klauzule*)
je default
while getopts r: opt; do case $opt in r) r=$OPTARG;; *) echo "Usage: $0 [-r DEEP]";; esac done
- Formátovací string:
- Stažení jedné stránky – pomocí příkazu
wget
s nastaveným výstupem přepínačem-O
- Hodí se použít dočasný soubor získaný pomocí
mktempt
t=$(mktemp) wget -O "$t" "$url" 2>/dev/null
- Hodí se použít dočasný soubor získaný pomocí
- Získání emailových adres – vhodným použitím regulárních výrazů a příkazu
grep
- Přepínač
-E
zapíná extended regexy, přepínač-o
způsobuje výpis pouze matchnutých částí
grep -Eo "[a-zA-Z0-9+.-]+@[a-zA-Z0-9+.-]+" < "$t" >> mailove_adresy.txt
- Přepínač
- Získání odkazů – pomocí
sed
u- Odkazy jsou ve tvaru
href="..."
, zkonstruujte si pro ně regex - Přepínač
p
na konci sedového příkazus
ubstitute způsobí výpis nahrazené části
sed -n 's/.*href="\([^"]*\)".*/\1/p' "$t"
- Odkazy jsou ve tvaru
- Rekurzivní dotazy – potřeba zajistit:
- Zajistit, abychom stejný odkaz stahovali jenom jednou
- Omezit se jen na doménu danou původním odkazem (bonus)