sed (awk) optimieren

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

sed (awk) optimieren

Beitrag von Duff » 13.11.2008 16:06:35

Hallo,

vielleicht kann mir ja jemand einen optimierungsvorschlag für folgenden Code machen:

Code: Alles auswählen

cat file | sed -ne 's/<\([^>]Attribute\)>/<\1>\
/gp' |sed -ne 's/^.*<Name>\(.*\)<\/Name><Value>\(.*\)<\/Value>.*$/\1 \2/p' | awk 'BEGIN { { printf "%-30s %s\n", "Attribute", "Value" } { printf "%s\n", "-----------------------------------------------------
-------" } } { printf "%-30s %s\n", $1, $2 }'
Würde gerne die sed oder und awk Befehle ohne eine Pipe schreiben.
Das System ist allerdings ein HP-UX.

Die Datei ist wie folgt aufgebaut:

Code: Alles auswählen

<Attribute><Name>name1</Name><Value>value1</Value></Attribute><Attribute><Name>name2</Name><Value>value2</Value>...
Die Ausgabe sieht aktuell dann so aus:

Code: Alles auswählen

Attribute                      Value
----------------------------------------------
name1                          value1
name2                          value2

Oh, yeah!

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: sed (awk) optimieren

Beitrag von Meillo » 13.11.2008 18:11:52

Ha, ein sed/awk-Problem, da bin ich doch gerne zur Stelle *grins*

Ich komme zu folgender Variante:

Code: Alles auswählen

<file sed -ne 's/<\/Attribute><Attribute>/\
/g; s/<[^>]*>/ /g; p' | awk 'BEGIN { printf("%-30s %s\n", "Attribute", "Value"); print("------------------------------------------------------------"); }   { printf("%-30s %s\n", $1, $2); }'
Als erstes in einzelne Zeilen aufsplitten ... sonst passen die Daten nicht zur Funktionsweise von sed/awk, die zeilenorientiert arbeiten.
Dann alle XML-Tags einfach durch Leerzeichen ersetzen.
Und anschließend die Ausgabe mit AWK.

Mit nur einem Programmaufruf dürfte es schwer (oder zumindest umständlich) werden, da die Ausgangsdaten nur eine Zeile umfassen.
Use ed once in a while!

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: sed (awk) optimieren

Beitrag von Duff » 13.11.2008 18:32:21

Vielen Dank für das optimierte sed und awk Programm ;-)
Ich habe immer Probleme, wenn ich mehrere sed Befehle hintereinander ausführen möchte und nicht dass Ganze immer durch eine Pipe zutrennen .

Führe ich allerdings dein Beispiel ohne awk aus, dann sehen die Zeilen ein wenig merkwürdig aus.

Code: Alles auswählen

daniel@laptop:~/scripts$ cat sed.test.txt 
<daniel><Attribute><Name>name1</Name><Value>value1</Value></Attribute><Attribute><Name>name2</Name><Value>value2</Value><Attribute><Name>name3</Name><Value>value3</Value></Attribute><Attribute><Name>name4</Name><Value>value4</Value><Attribute><Name>name5</Name><Value>value5</Value></daniel>

daniel@laptop:~/scripts$ < sed.test.txt sed -ne 's/<\/Attribute><Attribute>/\
/g; s/<[^>]*>/ /g; p'
   name1  value1 
 name2  value2   name3  value3 
 name4  value4   name5  value5  

daniel@laptop:~/scripts$ < sed.test.txt sed -ne 's/<\/Attribute><Attribute>/\
/g; s/<[^>]*>/ /g; p'| awk 'BEGIN { printf("%-30s %s\n", "Attribute", "Value"); print("------------------------------------------------------------"); }   { printf("%-30s %s\n", $1, $2); }'
Attribute                      Value
------------------------------------------------------------
name1                          value1
name2                          value2
name4                          value4
Mal schauen, ob es morgen auch unter HP-UX funktioniert. Unter debian funktioniert ja schonmal.
Oh, yeah!

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: sed (awk) optimieren

Beitrag von rendegast » 13.11.2008 19:02:24

"</Attribute><Attribute>" ist nicht konsequent eingesetzt:

Code: Alles auswählen

...e>value2</Value><Attribute><Name>name3</...
Sollte sein:

Code: Alles auswählen

...e>value2</Value></Attribute><Attribute><Name>name3</...

Code: Alles auswählen

sed -ne 's/<\/Attribute><Attribute>/\
/g;...
vielleicht anders:

Code: Alles auswählen

sed -ne 's/<[/]*Attribute>/\n/g;...
also jedes Auftauchen von "Attribute" durch newline ersetzen.
Falls awk die leeren Zeilen ausgeben sollte, können diese ja auch noch ausgefiltert werden.

-------------------------------
Warum verwendet niemand andere Trenner?

Code: Alles auswählen

sed -ne 's@</*Attribute>@\n@g;...


Mal schauen, ob es morgen auch unter HP-UX funktioniert
Script-Header "#!/bin/sh"
'sed --posix'
'awk --posix'
Zuletzt geändert von rendegast am 13.11.2008 19:17:58, insgesamt 1-mal geändert.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: sed (awk) optimieren

Beitrag von Meillo » 13.11.2008 19:16:37

rendegast hat geschrieben:"</Attribute><Attribute>" ist nicht konsequent eingesetzt:

Code: Alles auswählen

...e>value2</Value><Attribute><Name>name3</...
Sollte sein:

Code: Alles auswählen

...e>value2</Value></Attribute><Attribute><Name>name3</...
Ja, die Beispiel-Daten von Duff sind nicht ganz optimal. Es wurde etwas viel weggelassen.

Ich bin von korrekt gesetzten XML-Tags ausgegangen.

Alternativ führt der Ansatz von rendegast sicherlich zum Erfolg:

Code: Alles auswählen

sed -ne 's/<\/Attribute><Attribute>/\
/g;...
vielleicht anders:

Code: Alles auswählen

sed -ne 's/<[\/]*Attribute>/\n/g;...
also jedes Auftauchen von "Attribute" durch newline ersetzen.
Und falls Probleme bei der Ausgabe auftauchen,
dann noch die leeren Zeilen ausfiltern.
dazu kann man den letzten Block des AWK-Programms ja einfach nur für nicht-leere Zeilen anwenden:

Code: Alles auswählen

/./{ printf("%-30s %s\n", $1, $2); }
Use ed once in a while!

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: sed (awk) optimieren

Beitrag von Duff » 14.11.2008 08:17:08

Danke euch beiden, so funktioniert es.

Aber warum habe ich soviele Leerzeilen bei dem sed-Ergebnis und wieso kann ich diese Leerzeilen nicht noch mit sed '....;/^$/d;p' löschen?
Oh, yeah!

Antworten