Array predati na awk-program-kako?

Usutili mi se nesto nasi programeri ( ili su mozda jako zaposljeni ? ) a tako su mi potrebni. Mucim se sa jednim array-jom kojeg bi da predam na awk ali ovaj mi javlja gresku.


echo ${array[0]} | awk ' BEGIN { $1=????kako dalje

Nasao sam neku dokumentaciju o awk-u u netu ali nigdje nije objasnjeno kako se ponasaju varijable ( i array ) u awk-u. Dali mogu arry-e direktno preuzeti iz shella, ili ih moram deklarirati?
Ponekad znam bit dosadan sa svojim pitanjima ali nadam se da ima i onih koji uzivaju pri rjesavanju zadataka :wink:

Mozda ne bi bilo lose da malo preciznije objasnis kakav niz zelis predati awk-u i zasto …

Ma nek si se ti nama javio pa makar ja i “osto bez rjesenja” :smiley:
Nisam htjeo da odma zakomplikujem stvar, a sad kad pogledam pitanje , stvarno je malo nerazumljivo. Potrebna mi je funkcija kojoj ću predati npr. 3 broja, i ta funkcija treba da mi izlista sve moguće kombinacije sa ta tri broja.
To ti je sigurno poznato iz profi-svijeta pod nazivom kombinacija sa ponavljanjem. Tačnije rečeno potrebna mi je tkz. permutacija bez ponavljanja i kao što sigurno znaš i to je jedna vrsta kombiniranja, samo što ovdje rijedoslijed igra važnu ulogu.
Eh, ja ti te algoritme sve imam u C code-u, i sad bi da ih realizujem sa bash-om. Pošto awk ima vrlo sličnu sintaksu C-a, mislio sam da jednostavno pokušam sa awkom ( for i printf su identični).
Ali šta raditi ako su ta tri broja definisani kao varijable u sklopu mog skripta ?
Kako ih predati awku ? Nije mi jasno kako awk postupa sa varijablama unutar skripta. Osim toga se postavlja pitanje , kako predati arrey sa više elemenata, tako da te elemente mogu manipulirati unutar awk programa.

Evo upravo sam stigao iz knjižare sa knjigom “awk & sed” koja ima nekih 300 stranica. Ako bog da, uskoro idem za Tuzlu pa ću imat šta čitat.
A za sada mogu samo da se oslonim na iskustvo drugih.
hvala za pomoć
+study+

Knjiga je zakon. Samo što je otvori, nađoh rješenje:

$ declare -a array
$ array[0]=kk
$ array[1]=vozi
$ array[2]=golfa
$ echo ${array[@]} | awk '$1=="kk" { printf(" %s %s %sn", $1, $2, $3)}'
 kk vozi golfa

sad još samo da upotrijebim ovo na permutaciju +study+

Jaao, pa ovaj awk je stvarno mocan, svaka cast. Ne razumijem samo kako awk moze da obradi jednu datoteku pa da je ponovo pod tim imenom osigura ? Dali se rezultat moze prikazati samo na izlazu ?
Pri programiranju sam naisao na to pitanje.
Recimo da imam datoteku test.txt iz koje zelim izbrisati sve redove koji ne sadrze nista. Nakon sto sam ih izbrisao trebao bih rezultat poslati ponovo na tu datoteku.
Jedino rjesenje koje sam ovdje mogao pronaci je pravljenje druge datoteke u kojoj se usmjeri izlaz te mijenjanje njenog imena pomocu mv.
Sigurno je rjesenje puno jednostavnije, ali kod toliko opcija i mogucnosti nerazumijes vise najednostavnije stvari :-k

Preporucio bih svim Linux-korisnicima da ne pocinju sa shell-programiranjem, jer se mogu zaraziti ovako kao ja. +study+

Evo kako sam to rijesio sa sed-om:

test.txt
drugi red
treci red
cetvrti red

sesti red

osmi red

Brisanje praznih redova:

[code]
$ sed -n -e ‘/^$/!p’ test.txt > test1.txt
$ mv test1.txt test.txt

[/code] 8-[

Ovo mozes uraditi na vise nacina (uz redirekciju stdout-a, naravno), koristeci direktnu i inverznu logiku kod regularnog izraza za prazan red, a sto se tice filtera, to je stvar ukusa :slight_smile:

[1] prikazi svaki red koji sadrzi bar jedan karakter

    $ sed -n '/./p' test.txt > test1.txt
    $ mv test1.txt test.txt

    ili

    $ grep '.' test.txt > test1.txt
    $ mv test1.txt test.txt

    ili

    $ awk '/./ { print }' test.txt > test1.txt
    $ mv test1.txt test.txt

[2] prikazi sve redove, osim onih koji ne sadrze ni jedan karakter

    $ sed '/^$/d' test.txt > test1.txt
    $ mv test1.txt test.txt

    ili

    $ grep -v '^$' test.txt > test1.txt
    $ mv test1.txt test.txt

    ili

    $ awk '!/^$/ { print }' test.txt > test1.txt
    $ mv test1.txt test.txt

Idealno rjesenje za pisanje nazad u isti fajl ne postoji, jer velicina fajla nakon editovanja nije unaprijed poznata, a cak i da jeste, takvo rjesenje bi uzasno uticalo na performanse, jer bi pola vremena bilo potrebno za premijestanja sadrzaja i slicne operacije, koje se opet ne uklapaju u filozofiju UNIX-a. Mnogo je jednostavnije napraviti novi fajl i u njega upisivati sadrzaj i to je jedino rjesenje koje se koristi.

Sto se tice awk-a, on je super za odredjene stvari, ali, koliko je meni poznato, nema opciju za in-place file editing. Zato ima perl:

[3] _prikazi_ svaki red koji sadrzi bar jedan karakter
    i snimi rezultat u fajl test.txt umjesto prikazivanja na terminalu

    $ perl -n -i -e 'print if /./' test.txt

[4] _prikazi_ sve redove, osim onih koji ne sadrze ni jedan karakter
    i snimi rezultat u fajl test.txt umjesto prikazivanja na terminalu

    $ perl -n -i -e 'print unless /^$/' test.txt

Perl koristi opciju -i za in-place editing, tako da sve prikazane linije bivaju snimljene u fajl test.txt, pri cemu se prethodni sadrzaj fajla test.txt gubi (postoji mogucnost da se napravi backup starog fajla, ako se na opciju -i doda sufiks, ali to vidi u man perlrun).

Iako je ovo rjesenje elegantnije sa aspekta kucanja, u sustini se i ono svodi na pravljenje novog fajla:

$ strace perl -n -i -e 'print if /./' test.txt 2>&1 | egrep '(unlink|open)("test.txt'
open("test.txt", O_RDONLY|O_LARGEFILE)  = 3
unlink("test.txt")                      = 0
open("test.txt", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0666) = 4

Ovo je pravo dobar fol :wink: – perl otvori fajl test.txt za citanje (O_RDONLY) i dobije deskriptor 3. Posto ima ovaj deskriptor, ime fajla mu vise nije potrebno, pa ga bachi sa unlink. Onda opet poziva open da napravi novi fajl (O_CREAT) opet sa imenom test.txt, koje je upravo oslobodio. Ovdje se radi o drugom fajlu, koji je otvoren za pisanje (O_WRONLY). Sada je sve ostalo obicno prepisivanje iza kulisa:

1. citaj red sa deskriptora 3
2. ako ima barem jedan karakter u tom redu, pisi taj red na deskriptor 4
3. ako ima jos za citanje goto 1 :)

Zamisli da imas ovu situaciju:

$ cat test.txt
prvi red

treci red
$ ( sleep 60 ; cat ) < test.txt &
$ perl -n -i -e 'print if /./' test.txt
$ cat test.txt
prvi red
treci red
$

PITANJE: Sta ce se desiti kada prodje 60 sekundi spavanja?


PS: Sve ove stvari sa regularnim izrazima i filtriranjem mozes rijesiti uz malo interaktivnosti i sa vi editorom. U slucaju brisanja praznih redova iz fajla, to je:

$ vi test.txt

# Kad se otvori vi, kucas:

:g/^$/d
:wq

To je to.

[quote][3] prikazi svaki red koji sadrzi bar jedan karakter
i snimi rezultat u fajl test.txt umjesto prikazivanja na terminalu [/quote]

E, nemam taj rok. Sta si dobio? :slight_smile:

ma znam da bi moglo, samo stvar je u programiranju. Radi se o skriptima koje ce da pamte neke stvari, tj pisu te stvari u txt datoteke. Awk i sed su ti koji ce to automatski uraditi za korisnika iako on promijeni neke informacije.
kasnije kad pokrenes taj skript nakon godinu dana, imas sacuvane informacije.
Znaci nisam bio sa svojim postupkom ni toliko daleko.
Sto se tice Perl-a, tu sam totalni laik i najvjerovatnije cu i ostati, jer studirajuci bash, vidio sam da je sve “kucne zadatke” potpuno dovoljno.
Prije sam pokusavao i sa C-om da pravim ovakve tekstualne datoteke koje sluze za pamcenje informacija ali sam uvijek imao problema pri naknadnom obradjivanju tih datoteka. To je sigurno do mene, ali sad sam primjetio da je shell prava stvar za te zadatke.
Nego de ti meni reci koji program si koristio za onaj tvoj ASCII bash screensaver ( jpg2ascii ? ) 8-[

sado-mazo-vi-o :slight_smile:

$ cp ~/.exrc ~/.exrc~ ; echo -e ':e test.txtn:g/^$/dn:wq' > ~/.exrc ; vi ; mv ~/.exrc~ ~/.exrc

Ne moras biti tako pesimistican … perl je kombinacija shell-a, awk-a, sed-a i c-a, i jos vise od toga. Kada naucis koristiti sve ove navedene alate, neces imati problema da naucis i perl. Ako nista drugo, mozes prouciti perl-ove regularne izraze i vidjeces da se isplati :wink:

http://aa-project.sourceforge.net/aview/

Bas je zadovoljstvo citat’ ove vase thread-ove :slight_smile:
Palo mi je na pamet (zaboravio shljem) da pomenem python
mozda ne kao alternativu perlu nego kao jako interesantan
jezik. Nije mi stvarno namjera da startam shuplje diskusije tipa
najmijebolji …, nego mi se pravo svidio kada sam se malo
nesto igrao nedavno i tako rekoh 'ajde da podjelim.
Vise informacija na python sajtu,
a ukljucen je i u svaku linuks distribuciju.

Pozdrav

Naravno da sam bacio pogled i preko Python-a. Sigurno da je i ovo interesantan intepreter, jer sam cuo da je idealan za kreiranje softverskih protutipova i da ima vrlo logicnu sintaksu. Holanđani su inače kreativni ljudi, najvjerovatnije zbog toga što im zakoni nisu toliko oštri +arasquirit+ Tu je naravno i Ruby kod kojeg se programeri kunu da je A i O za skriptanje.
Ja samo mogu reći da je steta sto je zivot tako kratak, inace bi dobro bilo u svakoj biti maher.
U zadnje vrijeme sam otkrio awk i priznajem da sam zadivljen idejom,sintaksom i moći. bez pretjerivanja mogu reći da se 98 % svih problema da rijesiti sa awk-om. awk je prava stvar i mislim da su ova trojica sto su ga izmislili zaslužili nobelovu nagradu. Hajde sad, svi isprobajte awk :smiley:
Sto se tice Perla, dovoljno je bilo kad sam vidio funkcije koje ti stoje na raspolaganju. Nije da sam pesimista, ali stvarno previse je to. Ili bolje receno, za neke ljude, kao npr. mene suvišno. To ti je isto kao i sa C++, postoji 20 mogućnosti riješiti isti problem. I onda se postavlja pitanje koju da uzmem.
Imao bi jos jedno pitanje onako usput: Imali specijalista za programiranje sa Lynx-om. Googlo sa danas ali nisam mogo ništa pronaći što se tiče programiranja sa ovim Browserom. Prije svega me interesuje kako programirati sa Lynx-om tako da na pojedinim stranicama mogu i Tastaturu emulirati, tj. ubaciti u svoj program.
Npr. Zelim da downlodujem samo određene informacije sa www.lugbih.org. Lynx mi kaže ako moj Browser ne podstiče frameve da kliknem na jedan link, i tek me onda “prošalta” dalje. Kako to programirati ? Dali je to uopće moguće ?

a 99% se rješava Emacsom! :slight_smile: a tek Mozilla

ha, ha, ha ,ha Naš Vedran, uvijek spreman da te raspoloži !
+sunny+

[-o< [-o< [-o<
[-o< [-o< [-o<
[-o< [-o< [-o<

[quote]Prije svega me interesuje kako programirati sa Lynx-om tako da na pojedinim stranicama mogu i Tastaturu emulirati, tj. ubaciti u svoj program.
Npr. Zelim da downlodujem samo određene informacije sa www.lugbih.org. Lynx mi kaže ako moj Browser ne podstiče frameve da kliknem na jedan link, i tek me onda “prošalta” dalje. Kako to programirati ? Dali je to uopće moguće ?[/quote]

Naravno … lynx pored interaktivnog moda ima i neinteraktivni, tako da ga mozes koristiti u skriptama. Kljucne dvije opcije su -source i -dump. Prva jednostavno prikazuje HTML kod zeljene stranice, a druga formatira stranicu i prikazuje ti na standardnom izlazu nesto slicno onome sto bi vidio u interaktivnom modu. Jos jedna interesantna stvar vezana za -dump opciju jeste da na kraju lynx stampa listu svih linkova koje je pokupio prilikom parsovanja stranice. Svaki link je oznacen rednim brojem u uglastim zagradama, a odgovarajuci URL nalazi se na pomenutoj listi pod istim rednim brojem. Npr. www.lugbih.org daje slijedeci dump:

[code]$ lynx -dump ‘http://www.lugbih.org/

FRAME: [1]forum

Ukoliko se stranica ne otvori odmah kliknite na ovaj [2]link.

References

  1. http://www.linux.org.ba/
  2. http://www.linux.org.ba/
    [/code]

Radi se, dakle, o stranici, koja sadrzi dva linka. Iako su u ovom slucaju oba linka jednaka, tebi je interesantan link broj 2. Eh, sad je do tebe … Ko hoce da koristi browser star 20 godina, koji cak ne podrzava ni frame-ove, nek se pati sa parsovanjem sadrzaja (salim se, naravno :). Ovdje je tvoj zadatak da u svoju skriptu ugradis inteligenciju, pomocu koje ces dobiti trazeni redni broj linka na koji bi inace kliknuo (kad bi moglo u lynx-u) u interaktivnom modu. Sve ostalo je UNIX:

P.S. Ovo je primjer za link broj 2. Kad pronadjes redni broj linka koji ti je interesantan, samo zamijeni 2 u sed-ovom regularnom izrazu sa tim brojem.

Sve jasno, nista mi vise ne treba +uzdravlje+