Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet werde

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet werde

Beitrag von pangu » 06.11.2012 11:01:16

Hi Leute,

ich mach ein "smbstatus -b" und möchte anschließend diese Ausgabe weiterverwenden. Leider werden bei dieser Ausgabe keine Tabs produziert, sondern es handelt sich um ganz normale Leerzeichen. Ich hab mit unexpand versucht spaces in tabs umzuwandeln, aber ich stehe dann vor dem Problem daß nur einige Leerzeilen in tab umgewandelt werden und andere nicht. Ich möchte eigentlich folgendes erzielen, damit ich das Ergebnis dann komfortabel durch die Kommandos "cut -f" oder "awk -F" durchjagen kann.

Wenn mehr als 2 Leerzeichen hintereinander erkannt werden, soll dieser gesamte Leerbereich egal wieviel trailiung und leeding spaces folgten als TAB umgewandelt werden. So wird ganz klar ein Wort wie Domain Users bestehen bleiben, wogegen "hostname sonstwas" durch einen Tab getrennt wird.

Ich hoffe ihr versteht was ich meine. Wie mache ich so etwas? mit unexpand? mit sed? und wie bringe ich da diese Funktion mit ein, dass bei einer Zeichenfolge von 10 Leerzeichen nicht 5 tabs gebildet werden sonder nur einer?

Ich habs mal so versucht:

Code: Alles auswählen

sed 's/  */\t/g' ursprungsdatei.txt > ausgabedatei.txt
aber das führt auch dazu, dass die Zeilenumbrüche verschwinden, wenn ich die ausgabedatei mit vi betrachte.

EDIT: Oh doch! es scheint zu funktionieren. Ich glaubs ja gar nicht :D hatte ne falsche eingabedatei genutzt bei meinem ersten Versuch.


EDIT2: zu früh gefreut. Leider wird mir damit auch zwischen dem Wort "Domain Users" ein Tab eingefügt. Und am Ende zwischen dem Hostname und der IP-Adresse wird kein Tag generiertr, wenn nur 1 Leerzeichen dazwischen war. Somit ist es blöd nach dieser Whitespace Erkennung zu arbeiten. Wie könnte ich denn sonst noch den Output von "smbstatus -b" weiterverarbeiten?

Hier das Beispiel einer smbstatus -b Ausgabe, damit das besser illustriert wird. Wenn ein Spaltenwert größer wie üblich ist (z.B. beim Hostnamen!) dann folgen 2 Leerzeichen und dann die IP-Adresse. Wenn aber der Hostname kürzer war, wird mit Leerzeichen einfach aufgefüllt, bis dann eben die IP-Adresse angezeigt wird. Und wenn der Hostname exakt 13 Zeichen lang ist, folgt danach nur ein einziges Leerzeichen bis zur IP-Adresse. Das macht mir den Strich durch die Rechnung :(

Code: Alles auswählen

1723      ameert        Domain Users  a00220a      (::ffff:192.168.200.138)
32584     jkaruvfw      Domain Users  a40512a      (::ffff:192.168.200.130)
20843     zwoelfzeichn  Domain Users  a50931a      (::ffff:192.168.200.149)
29265     sechs6        Domain Users  __ffff_192.168.200.203 (::ffff:192.168.200.203)
27216     fuenf         Domain Users  a70521a      (::ffff:192.168.200.115)
26063     neunchars     Domain Users  hostmaxmor   (::ffff:192.168.200.187)
Man sieht beim User "sechs6" dass der Hostname so komisch ausgelesen wurde und die Zeile quasi aus dem üblichen Format sprengt.
Zuletzt geändert von pangu am 06.11.2012 11:45:07, insgesamt 2-mal geändert.
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

syssi
Beiträge: 2951
Registriert: 24.12.2010 16:50:59
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Rheinland

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von syssi » 06.11.2012 11:26:06

Versuchs mal mit einem weiteren Leerzeichen im Sed vor dem Wildcard:

Code: Alles auswählen

sed 's/   */\t/g' ursprungsdatei.txt > ausgabedatei.txt

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von pangu » 06.11.2012 11:26:50

@syssi: das Problem liegt daran, wie smbstatus -b ausgegeben hatte. Siehe meinen editierten Beitrag mit Zusatzinfos.
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Benutzeravatar
hikaru
Moderator
Beiträge: 13911
Registriert: 09.04.2008 12:48:59

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von hikaru » 06.11.2012 11:35:21

Kannst du mal bitte die unbearbeitete Quelldatei sowie das gewünschte Zielformat jeweils in Code-Tags posten? Ich sehe nämlich weder wo du her kommst noch wo du hin willst.
Dein sed-Aufruf kann so nicht passen denn du hast je nach Sichtweise entweder die falsche Wildcard (* statt +) gewählt oder wie syssi schon erwähnte ein Leerzeichen zu wenig im Suchmuster. Hostname und IP-Adresse wirst du vermutlich gesondert behandeln müssen.

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von pangu » 06.11.2012 11:52:51

Original-Ausgabe durch den Befehl smbstatus -b :

Code: Alles auswählen

1723      ameert        Domain Users  a00220a      (::ffff:192.168.200.138)
32584     jkaruvfw      Domain Users  a40512a      (::ffff:192.168.200.130)
20843     zwoelfzeichn  Domain Users  a50931a      (::ffff:192.168.200.149)
29265     sechs6        Domain Users  __ffff_192.168.200.203 (::ffff:192.168.200.203)
27216     fuenf         Domain Users  a70521a      (::ffff:192.168.200.115)
26063     neunchars     Domain Users  hostmaxmor   (::ffff:192.168.200.187)
Mein Ziel (A) spaltenartige Ausgabe durch Tabs:

Code: Alles auswählen

ameert<tabs so viele wie nötig>a00220a<tabs so viele wie nötig>192.168.200.138
jkaruvfw<tabs so viele wie nötig>a40512a<tabs so viele wie nötig>192.168.200.130
...
eben so daß wirklich Spalten entstehen, egal wie lange eine Spalte wird. Es soll formatiert und leserlich ausgegeben werden auch wenn es Hostname mal hypotetisch gesehen 40 Zeichen lang ist
Mein Ziel (B): kommagetrennt damit ich es als .csv in Excel importieren kann

Code: Alles auswählen

ameert,a00220a,192.168.200.138
jkaruvfw,a40512a,192.168.200.130
...
Ich will aber nicht nur ein fertiges Schnippsel von euch erhalten, sondern ich will auch verstehen lernen was die jeweiligen Schalter und Expressions ausführen und bedeuten. Mein Ursprungsgedanke war, unabhängig ob Zeil A oder B, dass ich erstmal die Leerzeichen umwandle, weil ich dann viel einfacher awk oder cut verwenden könnte. Oder mache ich mir da unnötig Sorgen und kann diesen Schritt komplett überspringen, indem ich direkt mit awk oder cut arbeite und dort eine Delimiter-Funktion á-la / */ verwende? In Cut kann ich aber nur ein einzelnes Zeichen angeben. Und bitte erkläre mir noch den unterschied zwischen * und + den du angesprochen hattest.

Freue mich, falls mir das jemand erklären kann. Danke !
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

syssi
Beiträge: 2951
Registriert: 24.12.2010 16:50:59
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Rheinland

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von syssi » 06.11.2012 12:07:47

Der Unterschied zwischen Stern und Plus:

Das Zeichen vor dem Stern kann *kein* Mal, einmal oder oefter vorkommen.
Das Zeichen vor dem Plus muss einmal oder oefter vorkommen.

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von pangu » 06.11.2012 12:10:34

Ahhh. Danke! dann ist Plus natürlich genau richtig hier :) aber lautet dann der Syntax ?

sed 's/ + +/\t/g'

oder

sed 's/ +/\t/g' ?? <-- das hier funktioniert aber nicht ?
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

syssi
Beiträge: 2951
Registriert: 24.12.2010 16:50:59
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Rheinland

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von syssi » 06.11.2012 12:16:35

Du musst das Plus in diesem Fall leider excapen, damit es seine Funktion gewinnt. Den genauen Grund kann ich dir nicht sagen. Vermutlich eine SED-Eigenart:

Code: Alles auswählen

echo "test  test" | sed 's/  \+/-tabulator-/g'

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von pangu » 06.11.2012 12:22:47

Ok, funzt. Ist -tabulator- nur eine andere Schreibweise als \t oder gibts wichtige Sachen zu beachten?
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

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

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von Meillo » 06.11.2012 12:25:31

syssi hat geschrieben:Du musst das Plus in diesem Fall leider excapen, damit es seine Funktion gewinnt. Den genauen Grund kann ich dir nicht sagen. Vermutlich eine SED-Eigenart:
Eigentlich kann sed kein Plus, nur den Stern. Nur durch (unportable) Erweiterungen koennen manche sed(1)s auch das Plus. Das ist der Grund weshalb es escaped werden muss.

Allerdings kann jedes Plus auch durch einen Stern ersetzt werden, denn /a+/ ist aequivalent zu /aa*/.
pangu hat geschrieben:Ok, funzt. Ist -tabulator- nur eine andere Schreibweise als \t oder gibts wichtige Sachen zu beachten?
Nicht jedes sed kennt `\t'. Wenn du portabel bleiben willst, dann verwende den Tab literal.
Use ed once in a while!

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von pangu » 06.11.2012 12:33:56

Meillo hat geschrieben:dann verwende den Tab literal.
Wie verwendet man den Tab literal? :roll: Danke für die Erklärung übrigens. Aber wenn ich in meinem folgenden Beispiel das \+ durch * ersetze krieg ich zwei Leerzeichen zwischen dem Wort Domain Users. Das würde nicht funktionieren. Aber mit dem \+ klappt es.

Mein Einzeiler sieht momentan wie folgt aus:

Code: Alles auswählen

smbstatus -b | sed 's/  \+/\t/g' | awk '{print $2","$5","$6}' |sed 's/[(:)]//g'
Ich veränderte mit dem ersten sed-Aufruf die Ausgabe von "smbstatus -b" so, daß Leerzeichen >=2 durch ein Tab ersetzt werden. Damit kann awk oder cut problemlos arbeiten, da sie defaultmässig den tab als delimiter (separator) nutzen. Anschliessend filtere ich mit awk so, daß ich nur den Inhalt der zweiten, fünften und sechsten Spalte anzeige und das ganze durch ein Komma trenne. An dieser Stelle würde mich auch interessieren, wie ich nun ein Tab generieren könnte statt dem Komma. Und zu letzt schneide ich noch Doppelpunkte und Klammern aus. Was aber übrigbleibt sind vier aufeinanderfolgende ffff aus der IPv6 Adresse. Wie nehme ich die auch raus? Oder wie soll ich eurer Meinung nach den Output von smbstatus -b am Ende mit der IPv6/IPv4 Adresse so filtern, dass mir nur die IPv4 angezeigt wird?
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

syssi
Beiträge: 2951
Registriert: 24.12.2010 16:50:59
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Rheinland

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von syssi » 06.11.2012 12:51:50

Code: Alles auswählen

echo "test test" | awk '{print $2"\t"$1 }'
Und den ipv6 Prefix koenntest du so weg nehmen:

Code: Alles auswählen

echo "::ffff:192.168.200.115" | sed 's/::ffff://g'

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von pangu » 06.11.2012 13:03:57

Dann habe ich das jetzt so gemacht, und sieht gut aus wenn ich Kommas als Trennzeichen verwende.

Code: Alles auswählen

smbstatus -b | sed 's/  \+/\t/g' | awk '{print $2","$5","$6}' |sed 's/::ffff://g;s/[()]//g'
Eine Frage bleibt noch offen: dein Vorschlag mit awk '{print $2"\t"$1 }' würde ja so funktionieren, dass immer exakt ein Tab eingefügt wird. Die Ausgabe erfolgt aber natürlich nicht spaltenartig, denn es kommt darauf an wie lange (Zeichenanzahl) ein Wert ist. Kann man anstatt dem Tab auch sagen, er soll einfach bis zum nächsten Tabstopp gehen?
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von Cae » 06.11.2012 18:34:23

pangu hat geschrieben:
Meillo hat geschrieben:dann verwende den Tab literal.
Wie verwendet man den Tab literal?
Indem du nicht die escapte Form "\t" schreibst, sondern das Tab als richtiges Zeichen, das erscheint, wenn du die Tab-Taste drueckst. (Die Forensoftware hier killt Whitespaces allerdings, daher kein Beispiel.)
pangu hat geschrieben:Die Ausgabe erfolgt aber natürlich nicht spaltenartig, denn es kommt darauf an wie lange (Zeichenanzahl) ein Wert ist. Kann man anstatt dem Tab auch sagen, er soll einfach bis zum nächsten Tabstopp gehen?
Ich verstehe dich vermutlich falsch, denn genau das tut ein Tab eigentlich. Vielleicht liegt der Tabstop ja gerade dazwischen, sodass man bei manchen Zeilen mehrere Tabs braucht, um auf dasselbe Tabstop-Level zu kommen.

Das muesste man dann berechnen, was wiederum davon abhaengt, wie breit ein Tab sein soll. Klassisch waere die Breite von 8 Leerzeichen, haeufig aber auch 4. Man wuerde alle Daten einlesen, dann gucken, ob es irgendwo in der ersten Spalte der laengste Eintrag mit einfach breitem Tab (= ein Leerzeichen) laenger als der kuerzeste Eintrag mit maximalem Tab (= 4 || 8 Leerzeichen) ist und ggf. die kuerzeren auffuettern. Das tut man so lange, bis es passst, und anschliessend fuer jede Spalte.

Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

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

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von Meillo » 06.11.2012 20:30:46

pangu hat geschrieben: Aber wenn ich in meinem folgenden Beispiel das \+ durch * ersetze krieg ich zwei Leerzeichen zwischen dem Wort Domain Users.
Du sollst auch nicht nur `\+' durch `*' ersetzen. Wenn dann musst du den Teilausdruck der quantifiziert wird auch nochmal einfuegen. Um verstaendlich zu bleiben ein Beispiel. ;-) (Leerzeichen sind schlecht hinzuschreiben, deshalb nehme ich Buchstaben.) Sagen wir, du willst Folgen von zwei oder mehr `b's ersetzen, dann koenntest du das mit s/bb\+/x/ machen. Der Suchausdruck wird gelesen als: ``Ein `b', gefolgt von mindestens einem `b'.'' Mit dem Stern saehe das so aus: s/bbb*/x/. Gelesen als: ``Ein `b', gefolgt von einem `b', gefolgt von null oder mehr `b's.''

Ist jetzt alles klar? :-)


pangu hat geschrieben:Eine Frage bleibt noch offen: dein Vorschlag mit awk '{print $2"\t"$1 }' würde ja so funktionieren, dass immer exakt ein Tab eingefügt wird. Die Ausgabe erfolgt aber natürlich nicht spaltenartig, denn es kommt darauf an wie lange (Zeichenanzahl) ein Wert ist.
Vielleicht hilft dabei `column -t'.
Use ed once in a while!

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von pangu » 06.11.2012 22:03:06

Jo, habe das verstanden. Und danke für den Tip mit dem column Befehl. :THX:
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

wanne
Moderator
Beiträge: 7553
Registriert: 24.05.2010 12:39:42

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von wanne » 06.11.2012 22:54:51

So als Tipp: Ich habe einen alias, der mir sed duchr sed -E ersetzt. Das spart escaperei. Das funktioniert nämlich:

Code: Alles auswählen

sed -E 's/\ \ +/\t/g'
bzw.
sed -E 's/  +/\t/g'
(Leerzeichn im ersten Befehl nur der übersichtlichkeit halber ausecapde)
rot: Moderator wanne spricht, default: User wanne spricht.

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

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von Meillo » 07.11.2012 08:54:55

OT:
wanne hat geschrieben:So als Tipp: Ich habe einen alias, der mir sed duchr sed -E ersetzt.
Mein sed kann weder -r noch -E und POSIX kennt auch keines von beiden: http://pubs.opengroup.org/onlinepubs/96 ... s/sed.html
Ihr duerft diese Dinge ja gerne verwenden, aber beklagt euch nicht wenn euer sed mal nicht GNU sed ist.
Use ed once in a while!

wanne
Moderator
Beiträge: 7553
Registriert: 24.05.2010 12:39:42

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von wanne » 07.11.2012 11:21:57

Meillo hat geschrieben:OT:
wanne hat geschrieben:So als Tipp: Ich habe einen alias, der mir sed duchr sed -E ersetzt.
Mein sed kann weder -r noch -E und POSIX kennt auch keines von beiden: http://pubs.opengroup.org/onlinepubs/96 ... s/sed.html
Ihr duerft diese Dinge ja gerne verwenden, aber beklagt euch nicht wenn euer sed mal nicht GNU sed ist.
Nein, ERE sind in Posix drin: https://en.wikipedia.org/wiki/Regular_e ... xpressions
Wenn man das GNU-Zeug benutzt sind in BRE nur die meisten ERE sachen schon enthalten, ohne dass das Flag nutzt.
rot: Moderator wanne spricht, default: User wanne spricht.

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

Re: Wenn mehr als 2 Leerzeichen,soll das als TAB gewertet we

Beitrag von Meillo » 07.11.2012 11:37:52

wanne hat geschrieben: Nein, ERE sind in Posix drin: https://en.wikipedia.org/wiki/Regular_e ... xpressions
Ja, natuerlich sind ERE Teil von POSIX, aber sed verwendet BREs. :-P Siehe http://pubs.opengroup.org/onlinepubs/96 ... _116_13_02

Wenn man das GNU-Zeug benutzt sind in BRE nur die meisten ERE sachen schon enthalten, ohne dass das Flag nutzt.
Und damit haben wir eine weiter Art von REs in Unix. ;-)
Donald Knuth in Digital Typography, ch. 33, p. 649 (1999) hat geschrieben: I define UNIX as 30 definitions of regular expressions living under one roof.
Use ed once in a while!

Antworten