Fórum Ubuntu CZ/SK
Ostatní => Tipy a triky pro Linux => Téma založeno: nettezzaumana 24 Ledna 2008, 13:47:27
-
Fujtajbl vespolek..
V posledních dvou týdnech jsem byl nucen svým zaměstnavatelem oprášit své znalosti perlu. Tento článek je myšlen pouze jako malý úvod a závdavek pro toho, kdo neví o perlu zhola nic a má dostatečně hladový mozek a energie na to, aby se začal něco sám učit.
Na úvod je třeba zdůraznit, že pro alespoň lehce angličtinou dotčeného jedince, je o perlu skutečně mnoho kvalitní dokumentace v samotném systému v rámci manuálových stránek. Víc než 'man perl && man perltoc && man perlfaq' na začátek není třeba.
Co to je Perl?
Perl je univerzálně použitelný programovací jazyk původně vyvinutý jako nástroj pro manipulaci s textem a nyní rozšířený do vysokoúrovňového skriptovacího jazyka, který je schopen pokrýt většinu úkolů, pro které jsou nízko (assembler, ..) a středně (C/C++) úrovňové jazyky neohrabané.
Typické použití Perlu je jako mocná, rychlá a příjemná náhrada veškerého systémového skriptování a manipulace s textem a soubory za použití RE (regulární výrazy) namísto dnes již nepříliš konfortního jazyku awk a případně kombinace klasických nástrojů jako bash+awk+sed.
Perl podporuje OO (object-oriented) programování a říkám rovnou a dopředu :: začnete-li s Perlem, začněte rovnou OO, protože použitím modulů si ušetříte skutečně mnoho řádků vašeho programu a jak jedna stará prava říká: "no problem should be solved twice", moduly v perlu (pro ty, kdo stále ještě nerozumí o čem je řeč, tak modul je vložený objekt podobně jako v C '#include <math.h>') dnes pokrývají nezměrnou množinu všech běžných i exotických operací.
(Pro toho, kdo stále ještě nerozumí:: Perl samořejmě umí provést příkazy systému a píšeme-li systémový skript právě v něm // a začínáme -li s Perlem // máme bez použití OO velice často nutkání provádět určité operace přímo pomocí systémového interpretu namísto použití možností samotného Perlu, takže takový systémový skript začínajícího programátora v Perlu je pak často mix bashe (`ls -a`) a řídících struktur perlu).
Více o OO viz. 'man perlmod && man perlmodlib'.
Na závěr obecných informacích o Perlu je třeba zdůraznit, že česká dokumentace a manuály k perlu je bohužel dnes již lehce překonaná a evergreenová dílka, která lze z vod českýho internetu vylovit, jsou bohužel často 10let stará a tudíž nemoderní a zbytečně zjednodušující.
Jak začít?
Třeba tak, že si řekneme, že každý program v Perlu by měl začínat '#!/usr/bin/perl -w'. Ono '-w' tam není nutné, ale znamená, že budeme dostávat upozornění na nepřiřazené proměnné a jiné věci, které nejsou nejsou přímo chybou. Náš styl se tím pak vytříbí, protože jen bez upozornění, je náš program v tomto směru napsaný čistě.
Komentář je od znaku '#' do konce řádku, pokud to není v RE.
Začnem složitější verzí oblíbeného programu 'Hallo World!', který se v tomto případě bude jmenovat pozdrav.pl a vytiskne 'Hallo World!' pokud ho spustime bez parametru a jinak 'Hallo <parametry>!' (takze pokud spustime aka 'pozdrav.pl Pepa Novak' dostaneme 'Hallo Pepa Novak!'
(dále od tohoto řádku píši jako by to byl samotný program, takže komentáře začínají od '#' do konce řádku)
# od teď si pro lepší pochopení doporučuju příklady pastnout do editoru, který má nějakou 'syntax-highlight' ..
# samozřejmě je jasné, že na prvním řádku (což dále už nezdůrazňuji) musí stát::
#!/usr/bin/perl -w
print "Hallo World\n" unless @ARGV;
print "Hallo @ARGV!\n" if @ARGV;
exit 0;
# o '@ARGV' zatím potřebujeme vědět pouze to, že to jest speciální (vyhrazenná) proměnná obsahující všechny parametry příkazové
# řádky, se kterými jsme program spustili. V tomto nejjednoduším případě testu dostaneme 'true', pokud není @ARGV prázdná.
# Tento příklad byl zapsán typickým způsobem pro perl, což je semantika anglického jazyka spojená se C-like syntaxi. Někomu bude
# možná připadat tento zápis ze začátku přehlednější, jinak je to absolutne to samé ::
if(@ARGV) {
print "Hallo @ARGV!\n";
} else {
print "Hallo World!\n";
};
exit 0;
# všiměte si, že náš program je ukončen pomocí příkazu 'exit 0', což sice není nutné, ale každý slušný 'program pod kontrolou'
# by tak měl být ukončen.
# V rámci geniálního použití syntaxe anglického jazyka v kombinaci s programováním může náš příklad vypadat v rámci možností
# Perlu i následovně ::
print "Hallo World!\n" and exit if not @ARGV or
print "Hallo @ARGV!\n" and exit;
# V posledním příkladu si všiměte, kde nám končí příkaz (kde je ';').
# 'if not VYRAZ' je to samé co 'unless VYRAZ', 'if ! VYRAZ' a nebo 'if(!VYRAZ)'.
# 'and', 'not' a 'or' jsou v tomto případě operátory. Jak vidíte, závorka kolem podmínky není povinná, ale
# nelze se na to spolehnout vždy a platí tedy zláté pravidlo jazyka C : Máš-li pochyby, závorkuj!
# Tento způsob byl pouze demonstrace kombinace angličtiny s programováním v perlu a takovýto zápis ve skutečnosti asi mnoho
# programátorů nepoužije.
# V následujícím příkladu si rozšíříme náš program tak, že víc argumentů příkazové řádky bude považovat za více jmen a
# přidáme podmínku, díky které nepozdraví slušně Billa Gatese, pokud se vyskytne mezi jmény.
# Samozřejmě platí, že chceme-li předat 'Bill Gates', musíme to buď dát do uvozovek a nebo vyescapovat mezeru aka 'Bill\ Gates'.
# to je samozřejmě vlastnost Bashe a s Perlem to nemá co dělat.
# Jako první způsob zápisu uvedu konzervativní C-like syntaxi ::
if(@ARGV) {
foreach(@ARGV) {
if($_ =~ m/bill\ gates/i) {
print "there are no greetings for bill!\n";
} else {
print "Hallo $_!\n";
};
};
} else {
print "Hallo World!\n";
};
exit 0;
# trocha si náš příklad "podáme" ::
# Ale předtím, než si řekneme co to je cyklus 'foreach', si ještě uděláme malou odbočku k proměnným ::
# proměnné v perlu mohou být buď 'string' (skalarní proměnná), což je nejjednodušší typ proměné a má prefix '$',
# a nebo 'array' jako pole, což je parta stringů nastrkaná do proměnné s prefixem '@'.
@VSTUP = @ARGV; # duplikujeme pole @ARGV jako pole @VSTUP
$VSTUP = "@ARGV"; # přiřadíme obsah pole @ARGV jako řetězec do skalarni proměnné $VSTUP
$VSTUP2 = @ARGV; # přiřadíme počet prvků pole @ARGV do proměnné $VSTUP2
print "$VSTUP[0]\n"; # tiskneme prvni prvek (indexovany jako '0') pole @VSTUP
print "$VSTUP\n"; # tiskneme skalarní proměnnou $VSTUP. !! nemá nic společného s polem @VSTUP
print "$VSTUP2\n";
exit 0;
# Z příkladu je patrné, že jednotlivé prvky pole jsou přístupné pomocí indexu [0..x], kde 'x' je poslední prvek
# pole a můžeme ho získat také jako ::
print "$ARGV[$#ARGV]\n"; # tedy '$#ARGV' je ve skalárním kontextu (číslo) index posledního prvku @ARGV.
# z příkladů výše je taktéž patrné, že Perl je inteligentní a rozlišuje jako různé proměnné $VAR a @VAR ..
# pozor! prvek pole nás zajímá ve skalárním kontextu, takže se na něj ptáme jako $VAR
# jediný rozdíl by byl, kdyby nás jako pole zajímal pouze určitý rozsah indexu pole, potom bychom jako
# prefix mohli použít '@' ::
@VSTUP = @ARGV[0..1]; # vytvoříme nové pole @VSTUP, obsahující první dva prvky pole @ARGV
$VSTUP = "@ARGV[0..1]"; # vytvoříme skalární proměnnou $VSTUP obsahující jako řetězec
# první dva prvky pole @ARGV oddělené mezerou.. ('..' znamená rozsah.)
# Zpět ale k našemu zdravícímu programu::
# Cyklus 'foreach(@ARGV)' tedy proběhne tolikrát, kolik má pole @ARGV prvků a v každém průběhu bude manipulovat
# právě s jedním prvkem. O '$_' zatím potřebujeme vědět pouze to, že je to 'implicitní proměnná' a v kombinaci
# s 'foreach' obsahuje ve skalárním kontextu (jak jinak že, když má prefix '$') v každém průběhu aktuální prvek.
# další zajímavost je zde podmínka 'if($_ =~ m/bill\ gates/i)', kde operátor '=~' slouží k porovnání s RE, což
# je výraz uzavřený mezi '/' aka '/REGEXP/' a je zde syntaxe jako v sedu, tzn.::
$XX =~ s/xx/yy/; # nahradí ve skalární proměnné 'xx' za 'yy'
if($_ =~ m/bill\ gates/i) .. # splní se, pokud '$_' obsahuje ('m' jako match // odpovídat) "bill gates"..
# 'i' znamené case-insensitive // kdyby nás chtěl Bill převézt aka "bILL gAteS"
# jedna vychytávka na konec:
foreach(@ARGV) {
$_ =~ s/billy?\ gates/looser/i;
print "Hallo $_!\n";
};
# tyto 3 řádky normálně zdraví jako náš program výše, ale pokud se mezi jmény vyskytne 'bill gates',
# a nebo 'billy gates' (obyč RE: '?' značí nepovinný znak, kdyby byl bill skutečně záludný a pokusil se
# zamaskovat třeba jako 'billy gATes'), program ho nahradí slovem 'looser', takže pokusí-li se Billy
# pozdravit naším programem, dopadne následujícím způsobem::
# $ pozdrav.pl The\ Big\ Billy\ Gates
# Hallo The Big looser!
# $
# Jakékoliv jiné jméno se přirozeně dočká slušné odpovědi::
# $ pozdrav.pl "The Big Pepa Novák" Jarda\ Procházka The\ Master\ Mark\ Shuttelworth 'Jan Tleskač'
# Hallo The Big Pepa Novák!
# Hallo Jarda Procházka!
# Hallo The Master Mark Shuttelworth!
# Hallo Jan Tleskač!
# $
# A na závěr se ještě jednou podívejte na náš program výše, protože ho teď napíšu v naprosto stejné funkcionalitě,
# ale místo použité C-like syntaxe použiju typickou perlovskou syntaxi..
#
# Pevně doufám, že Vás tento malý úvod do Perlu alespoň trošičku zaujmul a snad i inspiroval k jeho podrobnějšímu
# ohledání, protože Perl je skutečně vyjímečný jazyk ..
print "Hallo World!\n" and exit 0 unless @ARGV;
foreach(@ARGV) {
print "there are no greetings for bill!\n" and next if($_ =~ m/bill\ gates/i);
print "Hallo $_!\n";
};
exit 0;
# a úplně na závěr si představte, jakej by tohle byl vopruz napsat v bashi..
;enjoy by ntz
;ps. A aby jste neřekli ještě nakonec že jsem Vás ošidil, tak zde jest verze tohoto programu v Bashi:
if [ -z "$1" ]; then
echo "Hallo World!"
exit 0
fi
for x in "$@"; do
if [ -z "$(echo "$x" | tr A-Z a-z | sed '/bill\ gates/d')" ]; then
echo "there are no greetings for bill.."; else
echo "Hallo $x!"
fi
done
exit 0
;pps. Bohužel mám v systému šeredný bug, který způsobuje děsivou pomalost vyhledávacího algoritmu v grepu při
; utf8 locale, takže proto zde řeším podmínku přes tr+sed a ne přes grep. Nicméně za poslední měsíc jsem
; si zvykl skutečně přirozeně, že "grepovat" jde sedem snad ještě důkladněji ;D
-
no, dost se mi tam rozbilo formatovani, ale cert to vem.
enjoy by ntz
-
uff. clovek se tu s necim sejri a pes potom ani nestekne..
;D
-
Haf
-
Bude pokracovani? ::)
-
jo, zde je::
man perltoc :D
-
:-\
-
Jestli se chces naucit Perl, tak koukni na tyhle odkazy:
http://www.linuxsoft.cz/article_list.php?id_kategory=210
http://www.root.cz/serialy/perlicky/
http://docs.linux.cz/programming/interpreted/perl/
A nebo si kup knizku od pana Satrapy Perl pro zelenace.. pro zacatek je dobra a da se sehnat za kilo.
http://www.neo.cz/perl_green.html
-
4ntz: Tyhle tutoriály by se dali mrsknout na wiki... samozřejmě bez toho fujtajblu vespolek. 8)
-
nice clanok :) , ze by dalsi jazyk do mojej zbierky ? :D
-
4ntz: Tyhle tutoriály by se dali mrsknout na wiki... samozřejmě bez toho fujtajblu vespolek. 8)
ok, muzeme nahradit "fujtajbl vespolek" treba "čures přátelé!" ..
;D
-
4ntz: Tyhle tutoriály by se dali mrsknout na wiki... samozřejmě bez toho fujtajblu vespolek. 8)
ok, muzeme nahradit "fujtajbl vespolek" treba "čures přátelé!" ..
;D
Nebo tě péro sombréro....
Fakt peckovej úvod, pro toho kdo neví kde začít: 3x hurá for nettezzaumana! ;D
-
ps. dulezite inklůdy ;) .. dokumentace by k nim mela byt v ramci manpagi a pouzivaji se pomoci 'use', takze ..
use strict; // man strict .. tohle je prvni vec pod hlavickou
use Getopt::Std; // modul na parsovani options
use Getopt::Long; // to same, akorat to umi i format '--option' a ma to vetsi moznosti
use File::stat; // statistiky souboru
use File::Spec // ruzna manipulace s nazvy souboru v Unixovem prstredi, ie. konverze cest apod
use File::Path; // manipulace s adresari
use IO::File; // modul pro manipulaci aka cteni a psani do souboru
use IO::Dir; // to same pro adresare
use IO::Poll; // pro kernelova volani
use Shell; // lepsi spousteni shelovych veci, nez za pouziti eval a nebo `prikaz`
tohle pro zacatek bohate staci .. built-in funkce jsou popsany v manualove strance "perlmodlib" .. stejne dostupne jsou i desitky a stovky dalsich funkci a modulu v repozitarich..
Dalsi uzitecne prikazy ::
perldoc perllocal // vypise pridane (tedy "nebundled") moduly
perl -MFile::Find=find -MFile::Spec::Functions -Tlwe 'find { wanted => sub { print canonpath $_ if /\.pm\z/ }, no_chdir => 1 }, @INC' // toto vypise vsechny (nainstalovane) dostupne moduly dle fyzickeho umisteni
apt-cache search perl | sed '/^perl/!d' | sort // vypise dostupne perlove baliky v repos
enjoy by ntz ;)
-
Sqělej návod. Pochopil sem to až k tomu: Co je to PERL? :D
No já se teď pustil do CSS a PHP, takže na tohle ještě asi chvíli nebudu mít sílu. :)
-
Jak to vidíte s budoucností perlu? Kdy bude perl 6? Premyslim o tom ze se perl naucim a budu v nem psat web. PHP je sice super, ale hledam neco noveho :) Nejsem si ale jisty, zda perl neni krok z5 a jestli to ma budoucnost ucit se ted perl (5). Nadruhou stranu me ten jazyk hodne zaujal ... Takze otazka zni: Má to smysl se učit perl (nejen) kvůli webu?
-
Jak to vidíte s budoucností perlu? Kdy bude perl 6? Premyslim o tom ze se perl naucim a budu v nem psat web. PHP je sice super, ale hledam neco noveho :) Nejsem si ale jisty, zda perl neni krok z5 a jestli to ma budoucnost ucit se ted perl (5). Nadruhou stranu me ten jazyk hodne zaujal ... Takze otazka zni: Má to smysl se učit perl (nejen) kvůli webu?
<< odpoved zni :: jiste .. perl je v unixech jeden z nejpouzivanejsich systemovych jazyku a stale bude
-
...
No nic, vzdávám se. Inspiroval jsi mě k tomu, abych se tím začal hlouběji zabývat - od ledna jsem odolával a jen tak okrajově pomrkával, ale prázdniny končí a něco málo bych se naučit mohl... :)
-
(http://i.iinfo.cz/urs/Programming-republic-of-perl-120170599977295.png)
.. dnesni dil perlicek na rootu je pozruhodny .. (http://www.root.cz/clanky/perlicky-dalsi-cteni/)
.. jinak serial perlicky je vubec bozi ;) .. (http://www.root.cz/serialy/perlicky/)
-
btw. nouze na POSIX compliant systemech me donutila postupne opoustet sed, grep apod .. jedina moznost na plnohodne RE je prave perl ::
# ip a | perl -ne 'next if ! s/^\d+:\s+(.[^:]*):.*/\1/; print'
lo
eth0
wifi0
ath0
# cat /etc/group | perl -ne 'next if ! s/^(.[^:]*).*($ENV{"USER"}).*/\1/; s/\n/\ /g; print'; echo
audio beagleindex cdrom dialout disk kvm modem pulse pulse-access uucp video users
-
$ ls -1
Bad Religion - Against the Grain (1990, V0)
Bad Religion - Back To the Known (1984)
Bad Religion - Bad Religion (1981)
Bad Religion - Generator (1992, V0)
Bad Religion - How Could Hell Be Any Worse (1982, V0)
Bad Religion - Into the Unknown (1983, V0)
Bad Religion - New Maps of Hell (2007, V0)
Bad Religion - No Control (1989, V0)
Bad Religion - No Substance (1998, V0)
Bad Religion - Recipe For Hate (1993, V0)
Bad Religion - Stranger Than Fiction (1994, V0)
Bad Religion - Suffer (1988, V0)
Bad Religion - The Empire Strikes First (2004, V0)
Bad Religion - The Gray Race (1996, V0)
Bad Religion - The New America (2000, V0)
Bad Religion - The Process Of Belief (2002, V0)
B-Sides and Rarities
Covers By Bad Religion
Suffer Demos
$ ls -1 | grep ^Bad | while read line; do mv "$line" "$(echo $line | perl -ne 'next if ! s@^(.[^-]*)-(.*)\ \((\d+).*@$1\[$3\]$2@; print')"; done
$ ls -1
Bad Religion [1981] Bad Religion
Bad Religion [1982] How Could Hell Be Any Worse
Bad Religion [1983] Into the Unknown
Bad Religion [1984] Back To the Known
Bad Religion [1988] Suffer
Bad Religion [1989] No Control
Bad Religion [1990] Against the Grain
Bad Religion [1992] Generator
Bad Religion [1993] Recipe For Hate
Bad Religion [1994] Stranger Than Fiction
Bad Religion [1996] The Gray Race
Bad Religion [1998] No Substance
Bad Religion [2000] The New America
Bad Religion [2002] The Process Of Belief
Bad Religion [2004] The Empire Strikes First
Bad Religion [2007] New Maps of Hell
B-Sides and Rarities
Covers By Bad Religion
Suffer Demos
-
## vypise environment pro foo
perl -e 'chomp($PROC = `pidof foo`); open("X", "/proc/$PROC/environ"); $x = do { local $/; <X>; }; close("X"); $x =~ y/\0/\n/; print $x'
## vypise environ aktivniho procesu
perl -pe 'y@\0@\n@' /proc/$$/environ
.. s tim je spojena jedna otazka, pac proc vypisuje pouze prvnich 4096B (1 page) .. napada nekoho metoda, jak vypsat 100% veskery environment pro danou app ??
-
http://www.perl.org/books/beginning-perl/
-
ps. pokud pouzijete modul Shell, tak s perlem lze delat neskutecne veci ::
perl -MShell -e {\
'print ls("-lh", "~")',\
'cp("/foo", "/org")',\
'print echo("-e", "cures pratele\n")'}
-
do det zu mivulm ezuop micijudelsan :mebosupz ;)
#!/usr/bin/perl -w
foreach(@ARGV) {
print scalar reverse ." ";
}
print "\n";
.sp isjevilkso a enem ynletic sipaz ej :otkat
#!/usr/bin/perl -w
print scalar reverse ." " foreach @ARGV;
print "\n";
dukop emechc ticoto telpmok jelec ,gnirts emad oh od kevozovu
-
siht teppins fo edoc srevoc htob sesac nehw tupni si maerts ro tpircs si detucexe htiw dnammoc enil sretemarap ..
#!/usr/bin/perl -w
if (@ARGV) {
print scalar reverse ." " foreach @ARGV;
print "\n";
exit;
};
while (<>) {
@BLAH = $_;
@BLAH = split(/\s+/,join(",",@BLAH));
print scalar reverse ." " foreach @BLAH;
print "\n";
};
#!/usr/bin/perl -w
use strict;
if (@ARGV) {
foreach(@ARGV) {
print scalar reverse ." ";
};
print "\n";
exit;
};
while (<>) {
my @BLAH = $_;
@BLAH = split(/\s+/,join(",",@BLAH));
foreach(@BLAH) {
print scalar reverse ." ";
};
print "\n";
};
-
koukam, ze si vystacis sam ;D
-
etsij ukilrak ,); micatsyv
-
btw. info o dokumentaci k perlu ve Vasem ziskate napr. pomoci ::
apropos -s 3pm .
apropos perl
perldoc -f <funkce> ## vice viz `man perldoc`