Toon posts:

[nawk] te veel tussenbestanden

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik moest voor school een opdracht maken in unix met shellscripts en nawk.

De opdracht luidt als volgt:

een script schrijven dat een alfabetisch geordende lijst genereert van
de woorden die in een textfile (moet als argument worden meegegeven) voorkomen. Achter ieder woord moet een lijst komen van pagina- en regulnummers waarop dat woord voorkomt. Het aantal regels waaruit een pagina bestaat moet als argument aan het index script worden meegegeven.
Het programma moet ongevoelig zijn voor leestekens en hoofdletterongevoelig.
De uitvoerlijst en de lijst van lokaties per woord moet netjes geformatteerd
zijn. Je mag een te lange regel niet laten doorlopen op de volgende regel
maar je moet hem opsplitsen in meerdere regels.

Dit is al gelukt, maar ik heb 2 tussenbestanden gebruikt, en verder heb ik het idee dat het een stuk eenvoudiger kan, maar ik weet niet hoe.

Dit is wat ik heb:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cat $1 | 
tr '[A-Z]' '[a-z]' |
tr -cs '\012[a-z]' '[ *]' > gefilterd

for i in `cat gefilterd`
do
 echo $i >> woordenlijst
done

sort woordenlijst |
uniq > woordenlijst

for j in `cat woordenlijst`
do
 k=0
 echo $j `nawk '/^'"$j"' / || / '"$j"' / || / '"$j"'$/ {regel = NR % '"$2"';
 pagina = (NR - regel) / '"$2"' + 1;
 if (regel==0) {regel = '"$2"'; pagina = NR/'"$2"'};
 k=k+1;
 if(k==10){printf "\n\t";k=0};
 printf "%d(%d) ", pagina, regel}' gefilterd` | more
done
rm woordenlijst
rm gefilterd


Iemand idee hoe ik dit kan inkorten, of zonder tussenbestanden te doen?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 19-02 19:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

shellscript topics horen in de betreffende operatign system fora. Non-Windows Operating Systems dus in dit geval :)

PW -> NOS

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

sort -u <file>

-u = uniek.

Verwijderd

Topicstarter
en ik kom er net achter dat het stuk met de variabele k ook niet werkt.
Dus bij te grote regels blijft die op dezelfde regel doorgaan, terwijl de bedoeling was dat ie na 10 prints verder zou gaan op de volgende regel, maar dat werkt dus niet.

  • Wilke
  • Registratie: December 2000
  • Laatst online: 22:32
Dat komt omdat je moet schrijven k=$[k+1].

Je kunt zelfs doen:

code:
1
if [ $[k++] == 10 ]; then (linebreaks printen); fi

[ Voor 54% gewijzigd door Wilke op 09-06-2004 15:46 ]


  • yeadder
  • Registratie: Maart 2001
  • Niet online
echo $j `nawk '/^'"$j"' / || / '"$j"' / || / '"$j"'$/ {regel = NR % '"$2"'`;

???


misschien ipv een bestand, strings gebruiken.

Verwijderd

Topicstarter
Wilke schreef op 09 juni 2004 @ 15:44:
Dat komt omdat je moet schrijven k=$[k+1].

Je kunt zelfs doen:

code:
1
if [ $[k++] == 10 ]; then (linebreaks printen); fi
geprobeerd, maar hij geeft een foutmelding:

nawk: illegal statement at source line 4

  • llevering
  • Registratie: September 2000
  • Laatst online: 18-02 16:10
Hé mede I&E-er succes ermee :), ik zou wat eerder al met nawk aan de slag gaan, dan heb je zelfs helemaal geen tussenbestaande nodig. Bedenk dat je ook eerste lijst kan doorlopen in arrays kan stoppen en daarna met behulp van END { } de lijst kan sorteren en uitprinten.

Verwijderd

Topicstarter
Wilke schreef op 09 juni 2004 @ 15:44:
Dat komt omdat je moet schrijven k=$[k+1].

Je kunt zelfs doen:

code:
1
if [ $[k++] == 10 ]; then (linebreaks printen); fi
Ik heb dit geprobeerd, maar ik krijg syntax errors, volgens mij heb ik het niet op de juiste plaats geplakt, kun je misschien heel mijn code kopieren met daarin jouw aanpassing?

Verwijderd

Topicstarter
iemand nog idee waarom die k-loop niet goed werkt

Verwijderd

Topicstarter
code:
1
2
3
4
5
6
7
8
9
10
for j in `cat woordenlijst`
do
 k=0
 echo $j `nawk '/^'"$j"' / || / '"$j"' / || / '"$j"'$/ {regel = NR % '"$2"';
 pagina = (NR - regel) / '"$2"' + 1;
 if (regel==0) {regel = '"$2"'; pagina = NR/'"$2"'};
 k=k+1;
 if(k==10){printf "\n\t";k=0};
 printf "%d(%d) ", pagina, regel}' gefilterd` | more
done


De bedoeling van de variabele k is dat zodra er 10 keer dingen geprint zijn, dat ie dan op de volgende regel verder gaat om het netjes te houden. maar het werkt niet. Het geeft geen fout aan ofzo, maar ik kan m net zo goed weghalen want het heeft geen invloed. Ik denk dat het komt omdat de k=0 na de 'do' begint en dus nooit hoger dan 1 wordt, maar als ik m voor de 'do' zet krijg ik errors.
Dus iemand idee hoe ik dit moet laten werken?

  • Buffy
  • Registratie: April 2002
  • Laatst online: 26-12-2024

Buffy

Fire bad, Tree pretty

Begrijp ik het goed dat alles tussen echo en more een awk script is. Waarom staat k=0 dan boven het echo command en dus buiten het awk script?
Waarschijnlijk maakt het niks uit (in gawk heeft een niet-gedefineerde variable de lege string als waarde welke converteert naar 0 in een expressie) maar zet in het awk script (als eerste) het volgende:

code:
1
BEGIN { k= 0; }


Overigens lijkt me jouw manier van aanpak niet erg efficient. Eerst maak je een woordenlijst en dan ga je voor elk woord het bestand opnieuw doorlopen om de regelnummers te verzamelen.

Beter lijkt me als je een awk script maakt dat elk woord van een bestand filtert (heeft nawk functies als gensub?) en uitprint met het regel nummer (bv 'woord:regelnr'). De output van dit script pipe je dan naar het commando 'sort -t : -k 1,1 -k 2,2' (zie man sort). De gesorteerde output pipe je vervolgens naar een awk script dat daar dan een net overzicht van maakt.

Voordeel is dat je geen tussenbestanden nodig hebt en je maar een keer door het invoer bestand heen hoeft.

That which doesn't kill us, makes us stranger - Trevor (AEon FLux)
When a finger points at the moon, the imbecile looks at the finger (Chinese Proverb)


  • NetForce1
  • Registratie: November 2001
  • Laatst online: 18-02 10:22

NetForce1

(inspiratie == 0) -> true

Ha gezelli al die I&E-ers. Als aanvulling op llevering wil ik nog ff meedelen dat je de verwijzingen ook allemaal achter elkaar kunt plakken in een string, en daar indien nodig linebreaks tussengooien

De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"

Pagina: 1