Boli časy, boli, ale sa minuli, keď bolo treba nájsť najdlhší riadok v súbore (aby sa v C mohol alokovať dostatočne dlhý riadok pre fgets()
).
Pome! [Na GNU systémoch]
Ak máme GNU systém (teda bežný Linux), je to jednoduché:
wc -L /etc/passwd
Ale na BSD variantoch, medzi ktoré patrí MacOS, či na starých UNIXoidoch (AIX) to nestačí.
Vďaka Mariánovi Novákovi za prst do manuálu k tomuto parametru.
Pome! [Na MacOSoch]
Jedna zo zoznamovitých úvah ide takto: pre každý riadok spočítame jeho dĺžku, riadky zotriedime podľa dĺžky a vezmeme z výsledku poslednú (najväčšiu) hodnotu.
Inak povedané, zoznam riadkov namapujeme na zoznam dĺžok, ten potriedime a vytiahneme z neho posledný prvok.
Ak máme awk
, je to radosť: ten vie pracovať s riadkami jedna radosť. Stačí urobiť pre každý riadok akciu “vytlač dĺžku riadka”, a tú zistíme z internej funkcie length
.
Výsledok prerúrujeme do sort
u, ktorý to potriedi a posledný prvok vytiahneme tail
om:
awk '{print length}' /etc/passwd | sort | tail -n1
Pome! Aj s konkrétnym riadkom
Toto samozrejme vypíše len jedno číslo. Ale ja chcem vidieť aj oný riadok!
Tu už musíme viac awk
ovať: použime klasickú programátorskú fintu s hľadaním maxima.
Pre každý riadok zistíme, či jeho dĺžka je väčšia než doposiaľ dosiahnuté maximum a ak áno, aktualizujeme nové maximum a poznačíme si celý riadok. Na konci súboru všetko vypíšeme a máme to.
Skript maxdlzka.awk
by vyzeral:
{
if( length > max )
{
max = length
riadok = $0
}
}
END {
print max "|" riadok
}
V tomto skripte máme dve pravidlá: jedno pre každý riadok a jedno END
po konci súboru.
Premenná $0
obsahuje celý aktuálne spracovávaný riadok, a ostatné premenné netreba nijak deklarovať, ani inicializovať.
Posledná podivná vec je tlač: print
má viacero parametrov oddelených medzerami: čiže vytlačí obsah premennej max
, za ňu dolepí pajpu |
a za ňu premennú riadok
.
A potom:
awk -f maxdlzka.awk /etc/passwd
Ako správni hardcoráci to môžeme napísať aj na jeden riadok:
awk '{ if( length > m ) { m = length; l = $0 } } END { print m "|" l }' /etc/passwd