PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : AWK Frage (Anfänger)



hand44
17-02-2007, 14:49
Hallo,
mir kann bestimmt leicht geholfen werden, da ich wirklich ein blutiger Anfänger bis. Ich beschäftige mich erst seit heute mit awk und versuche damit ein kleines Programm zu schreiben, mit dem ich meine log-files auslesen kann.

Es geht um die Zeile:
sub("begin schema", "Form")

Diese ersetzt mir den String "begin schema" mit dem String "Form". Ich hätte allerdings gerne, dass das Programm das nur beim allerersten Treffer macht und nicht für jeden Treffer. Ich hab's mit einer while-Schleife versucht, das funktioniert aber nicht, weil das Programm scheinbar bei jeder Zeile neu durchlaufen wird.

Kann mir jemand verständlich erklären, was ich falsch mache?

Gruß und Danke,
S.

Romanday
17-02-2007, 19:02
Hallo,
Kann mir jemand verständlich erklären, was ich falsch mache?

Gruß und Danke,
S.

Setzte mal deine while() Schleife in den BEGIN{} Block.
Dann kannst Du auch wie gewohnt damit arbeiten.

hand44
17-02-2007, 21:31
Danke für den Tipp. Ich hab jetzt ne Weile probiert, aber krieg's einfach nicht hin. Könnte vielleicht jemand ein komplettes Skript für das unten stehende Beispiel schreiben? Das würde mir wirklich weiterhelfen. (Äh.. natürlich nur, wenn das nicht so lang ist. Ich glaube ja immer noch, dass das nur ein paar Zeilen sind...)
Wär total nett :)

Eingabe:
-------------
Gruppe: Obst
Name: Apfel
Farbe: grün
Gruppe: Obst
Name: Birne
Farbe: gelb
Gruppe: Obst
Name: Kirsche
Farbe: rot
Gruppe: Gemuese
Name: Karotte
Farbe: orange
Gruppe: Gemuese
Name: Kohlrabi
Farbe: grün
Gruppe: Gemuese
Name: Tomate
Farbe: rot
-------------

Ausgabe:
-------------
3 Obstsorten:
Apfel
Birne
Kirsche

3 Gemuesesorten:
Karotte
Kohlrabi
Tomate
-------------

Romanday
18-02-2007, 04:18
Äh.. natürlich nur, wenn das nicht so lang ist. Ich glaube ja immer noch, dass das nur ein paar Zeilen sind...)


Hab gerade mal ein wenig rumprobiert.
So einfach ist das nicht.
Reicht dir auch eine PHP Lösung?

hand44
19-02-2007, 08:03
Hallo Romanday,
danke für dein Angebot :). PHP halte ich nicht für so geeignet, da das Prog auch auf einem normalen Windows-Rechner laufen soll. Ich weiß auch nicht, ob PHP mit großen Textdateien so gut klar kommt wie AWK (30 Mbyte und größer).

Deshalb nochmal zu AWK. Ich denke, ich hätte einen Ansatz, wenn ich den Inhalt der jeweils nächsten Zeile abfragen könnte. Das hab ich aber bislang nicht hinbekommen. Also zB die Schleife
if($0 == "irgendwas") oder if($0 ~ "irgendwas")
wurde für jede Zeile ausgeführt, weil der Ausdruck $0 == "irgendwas" wohl immer wahr ist. Das kapier ich nicht so ganz. Weiß jemand, wie ich eine funktionierende Schleife der Art bauen könnte für das Beispiel oben? Also eine korrigierte Version von dieser:
if($0 ~ "Obst")

Danke,
sileem

rais
19-02-2007, 09:03
Moin moin,


Deshalb nochmal zu AWK. Ich denke, ich hätte einen Ansatz, wenn ich den Inhalt der jeweils nächsten Zeile abfragen könnte. Das hab ich aber bislang nicht hinbekommen. Also zB die Schleife
if($0 == "irgendwas") oder if($0 ~ "irgendwas")
wurde für jede Zeile ausgeführt, weil der Ausdruck $0 == "irgendwas" wohl immer wahr ist. Das kapier ich nicht so ganz. Weiß jemand, wie ich eine funktionierende Schleife der Art bauen könnte für das Beispiel oben? Also eine korrigierte Version von dieser:
if($0 ~ "Obst")

wenn ich das richtig sehe, dann ist z.B. bei der ersten Zeile Deiner Liste
$0 "Gruppe: Obst"
$1 "Gruppe:"
$2 "Obst"
frag also lieber if($1=="Gruppe:") und dann, ob Du $2 schonmal hattest;-)

Ist eigentlich gewährleistet, daß die Liste zmindest den Gruppen nach sortiert ist?
MfG,

hand44
19-02-2007, 11:08
Moin! :)
Durch den letzten Tipp und durch Ausprobieren bin ich jetzt noch einen Schritt weiter gekommen: Der Code:

BEGIN {
obst=1;
gemu=1;
sprit=1;
}

{
if($1=="Gruppe:")
{
if(obst==1 && $2=="Obst")
print "Obstsorten";
}
{
if(obst==1 && $2=="Obst")
obst=0;
}
{
if(gemu==1 && $2=="Gemuese")
print "\nGemuesesorten";
}
{
if(gemu==1 && $2=="Gemuese")
gemu=0;
}
}

sub("Name: ","");

bringt folgende Ausgabe:

Obstsorten
Apfel
Birne
Kirsche

Gemuesesorten
Karotte
Kohlrabi
Tomate

Jetzt fehlt mir noch die Anzahl der Obst- und Gemüsesorten an der jeweiligen Stelle. Geht das überhaupt?

hand44
19-02-2007, 14:32
So. Ich hab's jetzt fast komplett selbst hinbekommen :-). Ich hab nur noch eine letzte kleine Frage. Ich habe eine Eingabe nach der Art:

Name: 111 222 333 444 555

Und möchte per print nur ausgeben:
111 222 333 444 555

So hab ich's gemacht:
{
if($1==Name)
print $3,$4,$5,$6,$7
}

Das Problem ist, dass wenn ich eine Zeile habe wie zB
Name: 111 222
sieht die Ausgabe zwar auch brauchbar aus, aber für die überflüssigen Felder wird dann je ein Leerzeichen angehangen.

Meine Frage lautet also: Ist es direkt möglich, einfach alles rechts ab $3 auszugeben? Egal, wieviele Felder da stehen?

Gruß und Danke,
Sileem

undefined
19-02-2007, 22:27
Siehe man tr und wc

hand44
20-02-2007, 09:09
Äh... Uff!

Trotzdem Danke.

rais
20-02-2007, 09:20
mit awk vllt:
awk -F ":" '{ if($1=="Name") print $2 }' foo
so das ":"-Zeichen nur 1x pro Zeile vorkommt.
Hat's mit dem Zählen denn schon geklappt?
MfG,

hand44
22-02-2007, 09:53
Hi rais,

danke für den Tipp. Werde ich heute Nachmittag mal testen.
Das mit dem Zählen hab ich noch nicht in Angriff genommen. Wahrscheinlich mache ich das einfach unter den Haupttext - dann ist es wesentlich einfacher.

Gruß und Danke :)
Sileem