Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
-
Duff
- Beiträge: 6321
- Registriert: 22.03.2005 14:36:03
- Wohnort: /home/duff
Beitrag
von Duff » 13.07.2009 08:52:19
Hallo,
bekomme es mal wieder nicht hin ;-(
Habe eine Konfigdatei, die wie folgt aufgebaut ist
Code: Alles auswählen
...
[Section1]
param1=value1
...
#
#
[section2]
#
param1=value1
#---some comments
#
#---
[section3]
...
Ich möchte diese Datei nun gerne mit awk parsen.
Und zwar würde ich gerne immer einen Block von [sectionX] bis [sectionX] einlesen und in nur einer Zeile ausgegeben bekommen.
Habe es mit awk '/.../,/.../' und ORS probiert, aber es wird immer zu wenig ausgegeben.
Danke.
Zuletzt geändert von
Duff am 15.07.2009 08:17:16, insgesamt 1-mal geändert.
Oh, yeah!
-
Meillo
- Moderator
- Beiträge: 9254
- Registriert: 21.06.2005 14:55:06
- Wohnort: Balmora
-
Kontaktdaten:
Beitrag
von Meillo » 13.07.2009 09:37:59
Der erste Ansatz:
Die bessere Version (sogar kommentiert
):
Code: Alles auswählen
#!/usr/bin/awk -f
{
if (/^\[/) {
# insert newline if new section
print("")
}
# print line without line break
printf("%s ", $0)
}
Use ed once in a while!
-
gms
- Beiträge: 7798
- Registriert: 26.11.2004 20:08:38
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von gms » 13.07.2009 09:56:09
Duff hat geschrieben:
Und zwar würde ich gerne immer einen Block von [sectionX] bis [sectionX] einlesen und in nur einer Zeile ausgegeben bekommen.
Habe es mit awk '/.../,/.../' und ORS probiert, aber es wird immer zu wenig ausgegeben.
warum soll das nicht mit ORS funktionieren ?
Code: Alles auswählen
gms@gms2 ~ $ awk -F= -vORS=";" '/\[Section1\]/,/\[section2\]/{ if (/=/) print $1 "=" $2 } END{printf"\n"}' tmp/x.txt
param1=value1;param2=value2;
gms@gms2 ~ $
Gruß
gms
-
Duff
- Beiträge: 6321
- Registriert: 22.03.2005 14:36:03
- Wohnort: /home/duff
Beitrag
von Duff » 13.07.2009 19:19:46
Danke für die Antworten.
@Meillo: Den Einzeiler von dir kann ich noch nachvollziehen, auch wenn ich da so nicht drauf gekommen wäre.
Das Skript finde ich schon wieder etwas komplizierter. Nach meinem Verständnis durchläuft awk nämlich jede Zeile von oben nach unten durch.
Fängt eine Zeile mit [ an, so wird ein Leerzeichen ausgegeben, ansonsten die gesamte Zeile ohne das Newline-Zeichen (Zeilenumbruch).
Wieso finden denn trotzdem, wie gewollte, vor jedem Sektionsnamen [... ein Zeilenumbruch statt?
@gms: Ich wollte die Lösung allgemein. Hatte versucht den Bereich zwischen den Sektionen mit '/^\[.*/,/^\[.*/' einzugrenzen, was aber nicht funktioniert hat.
Oh, yeah!
-
Meillo
- Moderator
- Beiträge: 9254
- Registriert: 21.06.2005 14:55:06
- Wohnort: Balmora
-
Kontaktdaten:
Beitrag
von Meillo » 14.07.2009 11:17:17
Duff hat geschrieben:Das Skript finde ich schon wieder etwas komplizierter. Nach meinem Verständnis durchläuft awk nämlich jede Zeile von oben nach unten durch.
Fängt eine Zeile mit [ an, so wird ein Leerzeichen ausgegeben,
Falsch. Es wird eine leere Zeile (d.h. nur ein Newline) ausgegeben. Dadurch kommt vor jeder Zeile die mit eckiger Klammer beginnt ein Zeilenumbruch.
ansonsten
Falsch. Da ist kein `else'. Es wird also immer ...
die gesamte Zeile ohne das Newline-Zeichen (Zeilenumbruch).
... ausgegeben.
In einem Satz: Alle Zeilenumbrüche werden durch Leerzeichen ersetzt, vor jedem /^\[/ wird allerdings ein Zeilenumbruch eingefügt.
Use ed once in a while!
-
Duff
- Beiträge: 6321
- Registriert: 22.03.2005 14:36:03
- Wohnort: /home/duff
Beitrag
von Duff » 14.07.2009 12:20:42
Meillo hat geschrieben:
In einem Satz: Alle Zeilenumbrüche werden durch Leerzeichen ersetzt, vor jedem /^\[/ wird allerdings ein Zeilenumbruch eingefügt.
Aber wodurch wird ein Zeilenumbruch (\n) for jede Zeile die mit /^\[/ beginnt gesetzt?
In dem if steht doch nur ein print("");
Oh, yeah!
-
Meillo
- Moderator
- Beiträge: 9254
- Registriert: 21.06.2005 14:55:06
- Wohnort: Balmora
-
Kontaktdaten:
Beitrag
von Meillo » 14.07.2009 12:27:02
Duff hat geschrieben:Aber wodurch wird ein Zeilenumbruch (\n) for jede Zeile die mit /^\[/ beginnt gesetzt?
In dem if steht doch nur ein print("");
Genau. print() macht das gleiche wie `echo' in der Shell: Es gibt die übergebene Zeichenkette gefolgt von einem Newline aus. In diesem Fall also eine leere Zeichenkette gefolgt von einem Newline.
(Nicht zu verwechseln mit printf(), das _kein_ Newline ausgibt.)
Alternativ hätte ich `printf("\n")' schreiben können.
btw: Es gibt da eine sehr schöne Erklärung weshalb `echo' ohne Argument ein Newline ausgibt:
http://everything2.com/title/The%2520UN ... e%2520Echo
Diese Geschichte, die Sichtweise auf die Dinge die sie aufzeigt, ist für mich eine sehr gute Erklärung weshalb Unix so ist wie es ist.
Use ed once in a while!
-
Duff
- Beiträge: 6321
- Registriert: 22.03.2005 14:36:03
- Wohnort: /home/duff
Beitrag
von Duff » 14.07.2009 15:35:49
Danke für die Erklärung.
Kling eigentlich auch logisch...
Oh, yeah!
-
Meillo
- Moderator
- Beiträge: 9254
- Registriert: 21.06.2005 14:55:06
- Wohnort: Balmora
-
Kontaktdaten:
Beitrag
von Meillo » 14.07.2009 23:45:09
Duff hat geschrieben:Danke für die Erklärung.
Kling eigentlich auch logisch...
Immer gerne
Use ed once in a while!