Hallo Leute,
ich versuche aus dem Log von Yowsup Nachrichten zu filtern.
Bekomme es leider nicht hin.
Die interessante Zeilen sehen so aus:
1
[4912345678900@s.whatsapp.net(19-10-2015 22:36)]:[98A943B0CB31457F521D] Text
Was für mich interessant ist, ist die Nummer und der Text.
Die Ausgabe soll wie folgt sein:
1
4912345678900 text
Alle anderen Zeilen sollen verworfen werden.
Nur eingehende Nachrichten beginnen mit dem Zeichen "[".
Ich hab es probiert mit sed, awk und Grep. Bekomme es leider nicht
richtig hin :(
Könnte mir einer helfen?
Vermeidet auch Probleme, wenn im Text nochmals das Trennzeichen "]"
vorkommt.
btw. Kennt jemand eine bessere Alternative zu einer Schleife um alle
Felder ab einer bestimmten Position inkl. Trenner auszugeben?
Danke - diese RE sieht so aus, als ob sie den Zeilenaufbau korrekt
beschreibt: Beginnend mit "[", mindestens eine Zahl, gefolgt von "@", 0
oder mehr bliebige Zeichen, abgeschlossen von "]", mindestend 1 " " und
dann alle darstellbaren Zeichen bis zum Ende.
1
^(\[[\d]{1,})@.*\][\s]{1,}([\w]{1,})$
2
| | | | |||| | | | | |
3
| | | | |||| | | | | end
4
| | | | |||| | | | -----min 1
5
| | | | |||| | | ---------wchar
6
| | | | |||| | --------------min 1
7
| | | | |||| ------------------wspace
8
| | | | |||--------------------literal ]
9
| | | | ||---------------------min 0
10
| | | | |----------------------any char
11
| | | | -----------------------literal @
12
| | | ----------------------------min 1
13
| | ------------------------------- digit
14
| ----------------------------------literal [
15
------------------------------------begin
Wenn ich die RE aber in awk (gensub Funktion) oder mit sed (GNU sed
version 4.2.1 unter mingw32) verwenden will, gibt es Probleme.
Felder werden damit zwar definiert, sind aber identisch mit der
kompletten Zeile, wobei es gleichgültig ist, an welcher Position die
zusätzlichen Klammern stehen. Auch ein Escapen der vorhandenen Klammern
führt zum gleichen Verhalten.
Was mach' ich falsch?
[1] http://sed.sourceforge.net/grabbag/tutorials/sedfaq.txt
4.12. How do I parse a comma-delimited (CSV) data file?
Es gibt ja doch noch ein paar Spezialisten hier ;)
Nachdem die RE auf den ersten Blick korrekt aussah, hab ich erst gar
nicht versucht, daran etwas zu ändern.
Was den GNU sed betrifft sind die Quantifier {min, max} OK, während [\d]
anscheinend mit "\dxxx Produces or matches a character whose decimal
ascii value is xxx" kollidiert. Jedenfalls funktionieren alle Vorschläge
von S. J.
Auch hat Konrad S. Variante mich dazu gebracht über den Fehlerfall
nachzudenken - wenn mit dem s-Befehl etwas ersetzt wurde, explizit
ausgeben, ansonsten den pattern space löschen.
sed -r 's/^\[([[:digit:]]{1,})@.*\][[:space:]]+(.*)$/\1 \2/p;d'
10
11
$
Ich hab' das aber nicht vollständig durchgetestet, da es ja eigentlich
nicht mein Problem ist. Mich stören nur Fehler, die ich mir nicht
erklären kann. Danke jedenfalls für die Schubser in die passende
Richtung!
awk13 schrieb:> Auch hat Konrad S. Variante mich dazu gebracht über den Fehlerfall> nachzudenken - wenn mit dem s-Befehl etwas ersetzt wurde, explizit> ausgeben, ansonsten den pattern space löschen.
Irgendwie passt das nicht ganz zu meinen Überlegungen.
Konrad S. schrieb:> sed '/^\[/!d;s///;s/@[^ ]*//'
Der erste Ausdruck '/^\[/!d' kümmert sich um die Auswahl der gewünschten
Zeilen, denn
Hans schrieb:> Alle anderen Zeilen sollen verworfen werden.> Nur eingehende Nachrichten beginnen mit dem Zeichen "[".
Zeilen, die mit öffnender eckiger Klammer beginnen, werden nicht
gelöscht bzw. ohne Verneinung formuliert: nur Zeilen mit öffnender
eckiger Klammer am Zeilenanfang werden behalten.
Der zweite Ausdruck 's///' nutzt die Kurzschreibweise für "ersetze das
zuletzt gematchte" und löscht damit die öffnende eckige Klammer am
Zeilenanfang.
Der dritte Ausdruck 's/@[^ ]*//' löscht ab dem Klammeraffen alle Zeichen
bis vor das nächste Leerzeichen. Hier habe ich einfach angenommen, dass
der Text durch Leerzeichen abgetrennt ist.