Filtern von showrev -p

L

likwitt

Jungspund
Hallo zusammen,

auf der suche nach einer Lösung meines (kleinen) Problems bin ich auf dieses Forum gestossen und bin mir sicher das mir hier jemand weiterhelfen kann!
(zuvor noch ein grüßendes "hallo" an alle und bin von dem Forum positiv überrascht!)

Nun zu meinem Anliegen.
Ich möchte auf einem Solaris System alle Patche auflisten.
Dies gelingt auch mit dem Befehl
showrev -p
mit der Ausgabe
....
Patch: 119766-02 Obsoletes: Requires: Incompatibles: Packages: SUNWsfman
Patch: 120294-01 Obsoletes: Requires: Incompatibles: Packages: SUNWsfman
Patch: 120704-01 Obsoletes: Requires: Incompatibles: Packages: SUNWsfman
.....
Ich würde jedoch nur folgende Ausgabe benötigen:
Patch: 119766-02
Patch: 120294-01
Patch: 120704-01... ...

Wie kann ich das filtern?
Mit grep nach Patch ...und dann weiß ich jedoch nicht wie ich den Rest "wegschneide".
Vielleicht hat hier ja jemand nen Tipp.
thx im vorraus.
 
Hast Du unter Solaris cut? Dann geht vielleicht

Code:
showrev -p | cut -f1,2 -d" "

Für den Syntax schau Dir man cut an.

Gruss, Xanti
 
4 Minuten!!
und dann klappts auch noch :-)!
thx!!
 
Mist, es klappt. ;)

Hab mir noch andere Möglichkeiten überlegt (da ich mich mit Solaris nicht so auskenne), die ich der Vollständigkeit halber trotzdem angebe:

Code:
... | awk '{print $1, $2}'
... | sed 's/^\([^ ]* [^ ]*\).*/\1/'

Gruss, Xanti
 
Perl hast Du vergessen Xantüüüü :D
 
danke:-)
zur Vollständigkeit dann noch soviel ;-)
... | awk '{print $1, $2}' klappt nicht bei langen Zeilen
*** record `Patch: 118833-17 Obs...' has too many fields ***
... | sed 's/^\([^ ]* [^ ]*\).*/\1/' dagegen sieht wieder gut aus!!!

kann mich nur nochmals für die fixe Antwort bedanken.
Nun besteht natürlich die Gefahr das ich mich des öfteren hier mit sowas melde:-)!
(könnt ja gleich fragen wie ich das ganze dann nach Nummern listen kann ;-) )
 
zum einenmal wäre es sortieren.
Das andere wäre eine Art Spalten.
Mit Spalten meine ich die Ausgabe.
Momentan sieht diese ja folgendermassen aus.
Patch: 120739-02
Patch: 122208-01
Patch: 119890-03
Patch: 120288-02
Patch: 120286-02
Patch: 119262-03
...

und ist ziemlich lang.
Wünschenswärt wäre sowas in der Art
Patch: 120739-02 <TAB> Patch: 119890-03 <TAB> Patch: 120286-02
Patch: 122208-01 <TAB> Patch: 120288-02 <TAB> Patch: 119262-03


Somit hätte ich mehrere Spalten und die Liste wäre nicht endlos lang.
 
Nicht optimal, aber probier mal folgendes:

Code:
... | sort | perl -nae 'INIT{$i=0} print "$F[0] $F[1]"; if($i++==2) {print "\n"; $i=0} else {print "\t"} END{print "\n"}'

Gruss, Xanti
 
Hallo
Mein Vorschlag in Perl will ich auch noch zum Besten geben.
Hab ja lange keine Gelegenheit mehr gehabt gelle.;)
Code:
perl -ane '$sp=3;(($.%$sp)==0)?print:do{chomp;print "$_\t"};END{print"\n" if($.%$sp>0)}' temp/testei
testei ist hier die Eingabe statt der Pipe.
$sp ist die Anzahl der Spalten.
Wenn dir ein Newline am Ende doppelt oder fehlend egal ist, kannst du den ganzen ENDE Kram weglassen.

Aber wenn man schon Perl nimmt, könnte man gleich alles damit machen.:D

Gruß Wolfgang
 
... | awk '{print $1, $2}' klappt nicht bei langen Zeilen
*** record `Patch: 118833-17 Obs...' has too many fields ***
Das kommt jetzt darauf an, welchen awk Du verwendst - ist das auch der GNU-Awk? (meistens unter /usr/local/bin/awk unter Solaris zu finden)

@ Xantü, Wolle - subbi :-)
 
Welches awk das ist kann ich nicht sagen - Standard Solaris installation. (awk in /usr/bin ist irgendwie nicht richtig zu lesen)
Da es auf verschiedenen Solarisworkstation lauffähig sein sollte wären reine shell Befehle das Beste.

Aber die Lösung habt ihr mir ja schon geliefert - thx nochmals!

zur vollständigkeit noch dieses.
... | sort | perl -nae 'INIT{$i=0} print "$F[0] $F[1]"; if($i++==2) {print "\n"; $i=0} else {print "\t"} END{print "\n"}'
klappt bestens und zeigt mir das ganze in 3 Spalten. Werde noch herausfinden wie ich x-Spalten daraus bekomme - und was die einzelnen Sachen so machen:-)!

Die 2te Perllösung scheint nicht ganz so zu funktionieren
perl -ane '$sp=3;(($.%$sp)==0)?print:do{chomp;print "$_\t"};END{print"\n" if($.%$sp>0)}' temp/testei

habe showrev -p in eine Testdatei umgeleitet und diese dann für temp/testtei angegeben. Da "filtert" er jedoch leider nicht.


Meine Momentane Lösung geht jedoch von Perl weg (kann nicht wissen ob auf allen rechnern Perl korrekt installiert ist / Pfad usw.) und sieht folgendermassen aus:

showrev -p |cut -d" " -f1,2 | sort | awk '/^[a-zA-Z]/{h=$0} /^[a-zA-Z]/ {print h,","$0}'

hier versuche ich jedoch noch mehrere Spalten zu haben (mind. 4) und vielleicht mit TAB noch übersichtlicher zu machen.
Hat noch nicht ganz geklappt;-)
 
Zuletzt bearbeitet:
Hallo
Meine Lösung funktioniert unter *nixsystemen ohne Probleme:
Könnte es sein, dass deine Datei \r enthält?
Dann geht das natürlich nicht.
chomp entfernt das Newline der Eingabe.
$ cat testei
Patch: 120739-02
Patch: 122208-01
Patch: 119890-03
Patch: 120288-02
Patch: 120286-02
Patch: 119262-03
$ perl -ane '$sp=3;(($.%$sp)==0)?print:do{chomp;print "$_\t"};END{print"\n" if($.%$sp>0)}' testei
Patch: 120739-02 Patch: 122208-01 Patch: 119890-03
Patch: 120288-02 Patch: 120286-02 Patch: 119262-03

perl -ane '$sp=2;(($.%$sp)==0)?print:do{chomp;print "$_\t"};END{print"\n" if($.%$sp>0)}' testei
Patch: 120739-02 Patch: 122208-01
Patch: 119890-03 Patch: 120288-02
Patch: 120286-02 Patch: 119262-03

Falls das dein Problem ist, kannst du die daten ja vorher durch tr -d "\r" schieben.
Aber auch Xanties Lösung lässt sich umbauen.
Dafür musst du nur den Vergleich if($i++==2) auf die gewünschte Spaltenzahl setzen.

Gruß Wolfgang
 
Hallo Wolfgang,

ich vermute mal, likwitt wendet Deinen Befehl auf den Ausgangsstream an:

Code:
Patch: 119766-02 Obsoletes: Requires: Incompatibles: Packages: SUNWsfman
Patch: 120294-01 Obsoletes: Requires: Incompatibles: Packages: SUNWsfman
Patch: 120704-01 Obsoletes: Requires: Incompatibles: Packages: SUNWsfman

Gruss, Xanti
 
sorry, hatte wohl zur gleichen Zeit meinen Letzten Beitrag editiert!

Wie dort erwähnt versuche ich von der Perl Lösung abstand zu halten und Probiere es mit
showrev -p |cut -d" " -f1,2 | sort | awk '/^[a-zA-Z]/{h=$0} /^[a-zA-Z]/ {print h,","$0}'
um suícherzustellen das ich das auf allen Rechnern Problemlos durchführen kann.
Momentanes Problem habe ich das ich nur zwei Spalten bekomme (benötige mind. 4) und versuche noch mehr übersichtlichkeit (tabs) reinzubekommen.Vielleicht hat da jemand eine Idee?


und xanti hatte recht - hatte den Ausgangststream verwendet.
 
Zuletzt bearbeitet:
Hallo
Ob du mit awk portabler als mit perl bist, wage ich arg zu bezweifeln.

Hier noch ein sed-Hack.
Code:
$ sed -ne '$!{:a;N;s/\n/\t/g;p;d;b a};$p' testei
Patch: 120739-02        Patch: 122208-01
Patch: 119890-03        Patch: 120288-02
Patch: 120286-02        Patch: 119262-03
Patch: 123288-02        Patch: 124288-02
Patch: 125288-02        Patch: 126288-02
Patch: 127288-02        Patch: 128288-02
Patch: 129288-02

Wenn du drei Spalten willst, einfach ein weiteres N; einfügen.
Code:
$ sed -ne '$!{:a;N;N;s/\n/\t/g;p;d;b a};$p' testei
Patch: 120739-02        Patch: 122208-01        Patch: 119890-03
Patch: 120288-02        Patch: 120286-02        Patch: 119262-03
Patch: 123288-02        Patch: 124288-02        Patch: 125288-02
Patch: 126288-02        Patch: 127288-02        Patch: 128288-02
Patch: 129288-02
Um es für alle Shells portabel zu machen, verwende es einfach in einem Sed-Script.

Bei awk bin ich nicht richtig fit, da ich immer Perl statt awk verwende.
Hier trotzdem ein Hack, den ich auf die Schnelle zusammengebastelt habe.
MAX gibt die Spaltenzahl an.
Ohne Garantie auf Portierbarkeit.
Code:
$ awk  -v MAX=4 '{while((NR % MAX) > 0 ){if (NR==1 || L ==""){L=$0}a=getline;if(a>0){L=L "\t" $0}else{break}}print L;L=""}' testei

Patch: 120739-02        Patch: 122208-01        Patch: 119890-03        Patch: 120288-02
Patch: 120286-02        Patch: 119262-03        Patch: 123288-02        Patch: 124288-02
Patch: 125288-02        Patch: 126288-02        Patch: 127288-02        Patch: 128288-02
Patch: 129288-02
Sollte dein awk -v var=Wert nicht kennen, ersetze MAX direkt durch die gewünschte Zahl in der while Schleife.

Also verfeinere meine Vorschläge selbst.

Gruß Wolfgang
 
muß im vorhinein sagen das die ganzen Lösungen (und vorallem die Schnelle dieser) weit mehr ist als ich erwartet habe!!
thx nochmal!

zum letzten Beitrag / Vorschlag.

Um dies zu nutzen muß ich showrev -p immer vorher in eine Datei umleiten - das will ich noch umgehen - daher dachte ich an
*****
showrev -p |cut -d" " -f1,2 | sort | awk '/^[a-zA-Z]/{h=$0} /^[a-zA-Z]/ {print h,","$0}'
*****
und da eben die Spalten hinzufügen.

Aber die sed lösung gefällt mir auch (nur das sie eben auf eine datei angewand wird).
Werde das ganze nochmals durchgehn - ist viel Imput für einen der davon ansich nichts versteht:-)!

test ist die datei die zuvor mit
showrev -p |cut -d" " -f1,2 >> test
erstellt worden ist.

# awk -v MAX=4 '{while((NR % MAX) > 0 ){if (NR==1 || L ==""){L=$0}a=getline;if(a>0){L=L "\t" $0}else{break}}print L;L=""}' test
awk: syntax error near line 1
awk: bailing out near line 1
****
[/]# sed -ne '$!{:a;N;N;s/\n/\t/g;p;d;b a};$p' test
Label too long: $!{:a;N;N;s/\n/\t/g;p;d;b a};$p


abschließend
dickes thx und lob nochmal!
 
Zuletzt bearbeitet:
Hallo

Beide Vorschläge sollten auch aus einer Pipe funktionieren.

Ich habe kein Solaris, aber die meisten Probleme entstehen durch die Shellinterpretation.

Bei sed solltest du versuchen das was zwischen -e'...' steht in ein sedscript zu schreiben, welches du dann einfach lädst. Bei GNU sed ist das die Option -f.

Script würde dann so aussehen:
$ cat sedscript:
$!
{
:a;
N;
s/\n/\t/g;
p;
d;
b a
};$p

Was das macht ist schnell erklärt:
  • solange nicht letzte Zeile: ($!)
  • Das ist ein Label für den Loop (:a) #hier a genannt
  • Lade noch eine Zeile in den Patternspace (N)
  • entferne aus dem Patternspace das Newline und ersetze durch tabs/\n/\t/g
  • gib alles aus (p)
  • Lösche Patternspace (d)
  • Springe zu a (b a) # nächste Schleife
  • Letzte Zeile einfach ausgeben ($p) #damit auch unvollständige Spaltenzahl ausgegeben wird.
Das würdest du dann so aufrufen (GNU sed musst halt nachsehen, was dein sed für Optionen dafür hat)
...pipe|sed -f"sedscript"
Was dein awk da bemänglet, weiss ich nicht zu deuten.
Aber auch awk kann aus einem Script lesen.
Vorgehen wie bei sed.
Wobei sed die schnellere Variante sein dürfte.

Gruß Wolfgang
 
Zuletzt bearbeitet:
ok -

also nochmal zum grundsätzlichen,
scripte und perl sind leider keine Lösung, da ich nicht die möglichkeit habe scripte auf die zu überprüfenden Maschinen zu installieren.
Perl geht nur bedingt, da ich nicht zusichern kann das Perl auf all den zu überprüfenden Maschinen vorhanden ist, und fals doch, das der Pfad stimmt.

Somit bleiben nur direkte "shellbefehle" die mit den "Standard tools" (cat, cat ,awk, grep ...) das ergebniss bringen.
showrev -p | cut -d" " -f1,2 | sort | awk '/^[a-zA-Z]/{h=$0} /^[a-zA-Z]/ {print h,","$0}'| awk '/^[a-zA-Z]/{h=$0} /^[a-zA-Z]/ {print h,","$0}'

Momentan ist die verdoppelung des awk Befehls die simpelste Lösung um 4 spalten zu erhalten. (ob es performance technisch sinn macht - naja)
 
Hallo
Du kannst nicht mal eine Datei mit den paar Zeilen Script erzeugen?
Da verstehe ich sicher etwas falsch.
Na dann bliebe ja noch die normalen Shellmittel.
Welche Shell verwendest du denn?
Kannst du sicherstellen, dass es überall die gleiche ist?

Bashkompatibel sollte auch folgendes gehen.

Code:
$x=0;
cat testei|while read var; do ((x++));if [ $(($x % [color=red][b]2[/b][/color])) -eq 0 ]; then echo $var;else echo  -ne "$var\t"; fi;done&6echo
Patch: 120739-02        Patch: 122208-01
Patch: 119890-03        Patch: 120288-02
Patch: 120286-02        Patch: 119262-03
Patch: 123288-02        Patch: 124288-02
Patch: 125288-02        Patch: 126288-02
Patch: 127288-02        Patch: 128288-02
Patch: 129288-02        
x=0;
cat testei|while read var; do ((x++));if [ $(($x % [color=red][b]3[/b][/color])) -eq 0 ]; then echo $var;else echo -ne "$var\t"; fi;done&& echo ""
Patch: 120739-02        Patch: 122208-01        Patch: 119890-03
Patch: 120288-02        Patch: 120286-02        Patch: 119262-03
Patch: 123288-02        Patch: 124288-02        Patch: 125288-02
Patch: 126288-02        Patch: 127288-02        Patch: 128288-02
Patch: 129288-02

Wenn deine Shell ((x++)) nicht versteht, dann verwende den old Style.
x=$((x + 1));

Gruß Wolfgang
 

Ähnliche Themen

OpenVPN Zertifikate

Zurück
Oben