Forum: PC-Programmierung Textstellen in Log Filtern


von Hans (Gast)


Lesenswert?

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?

von noname (Gast)


Lesenswert?

man-pages gelesen?
regex gelernt?

von awk13 (Gast)


Lesenswert?

Wenn die erste Nummer eine konstante Länge hat:
1
$ echo "[4912345678900@s.whatsapp.net(19-10-2015 22:36)]:[98A943B0CB31457F521D]  Text1 text2" | awk -F']' '/^\[/{print substr($1,2,13) " " $3}'
2
4912345678900   Text1 text2

Sonst anhand des @ nochmals aufdröseln.

von Hans (Gast)


Lesenswert?

Super :) Danke :)

von awk13 (Gast)


Lesenswert?

Schön, dass es passt, auch wenn ich den Code für den zweiten Fall 
irgendwie weggeschnippselt habe.
1
$ echo "[49123456789004fs@s.whatsapp.net(19-10-2015 22:36)]:[98A943B0CB31457F521D]  Text1]text2]]text3" | 
2
sed 's/@/]/' | 
3
awk -F']' '/^\[/{printf substr($1,2) " " $4; 
4
for(i=5;i<=NF;i++) printf FS $(i); 
5
print ""}'
6
7
49123456789004fs   Text1]text2]]text3

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?

von Hmm... (Gast)


Lesenswert?

Regulärer Ausdruck:

^(\[[\d]{1,})@.*\][\s]{1,}([\w]{1,})$

Der erste Submatch wäre die Zahl, der zweite der Text dazu.

https://regex101.com/

von awk13 (Gast)


Lesenswert?

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.
1
$ echo "[49123456789004fs@s.whatsapp.net(19-10-2015 22:36)]:98A943B0CB31457F521D]  Text1 text2 text3" | 
2
sed 's/^(\[[\d]{1,})@.*\][\s]{1,}([\w]{1,})$/\1/'
3
sed: -e expression #1, char 43: invalid reference \1 on `s' command's RHS

OK - also mit \(...\) gruppieren, da kein Feld erkannt wird [1].
1
$ echo "[49123456789004fs@s.whatsapp.net(19-10-2015 22:36)]:98A943B0CB31457F521D]  Text1 text2 text3" | 
2
sed 's/^(\[\([\d]{1,})\)@.*\][\s]{1,}([\w]{1,})$/\1/'
3
4
[49123456789004fs@s.whatsapp.net(19-10-2015 22:36)]:98A943B0CB31457F521D]  Text1 text2 text3
5
6
$ echo "[49123456789004fs@s.whatsapp.net(19-10-2015 22:36)]:98A943B0CB31457F521D]  Text1 text2 text3" | 
7
sed 's/^(\[\([\d]{1,})\)@.*\][\s]{1,}([\w]{1,})$/\2/'
8
sed: -e expression #1, char 47: invalid reference \2 on `s' command's RHS
9
10
$ echo "[49123456789004fs@s.whatsapp.net(19-10-2015 22:36)]:98A943B0CB31457F521D]  Text1 text2 text3" | 
11
sed 's/^(\[\([\d]{1,})\)@.*\][\s]{1,}\(([\w]{1,})$\)/\2/'
12
13
[49123456789004fs@s.whatsapp.net(19-10-2015 22:36)]:98A943B0CB31457F521D]  Text1 text2 text3

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?

von Mikro 7. (mikro77)


Lesenswert?

Bei sed muss man manchmal aufpassen, welche "Version" der regulären 
Ausdrücke benutzt werden. Bei mir klappt bspw.:
1
> echo "[49123456789004fs@s.whatsapp.net(19-10-2015 22:36)]:[98A943B0CB31457F521D]  Text1 text2 text3" |  
2
sed 's/^\[\([^@]*\)@[^]]*\][^ \t][^ \t]*[ \t]*\(.*\)$/\1 \2/'
3
49123456789004fs Text1 text2 text3

Mit erweiterten regulären Ausdrücken (POSIX) sieht das etwas hübscher 
aus:
1
> echo "[49123456789004fs@s.whatsapp.net(19-10-2015 22:36)]:[98A943B0CB31457F521D]  Text1 text2 text3" | 
2
sed -r 's/^\[([^@]*)@[^]]*\][^[:space:]]+[[:space:]]+(.*)$/\1 \2/'
3
49123456789004fs Text1 text2 text3

Oder ganz einfach:
1
> echo "[49123456789004fs@s.whatsapp.net(19-10-2015 22:36)]:[98A943B0CB31457F521D]  Text1 text2 text3" |
2
sed -r 's/^\[(.*)@.*\][[:space:]]+(.*)$/\1 \2/'
3
49123456789004fs Text1 text2 text3

Take your pick.

von Konrad S. (maybee)


Lesenswert?

1
sed '/^\[/!d;s///;s/@[^ ]*//'

von JJ (Gast)


Lesenswert?

Schau dir mal die man-page von cut an.
Für einfache Anforderungen wie feste Feldgrößen gibt es nichts 
simpleres.

von awk13 (Gast)


Lesenswert?

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.
1
$ echo "[49123456789004@s.whatsapp.net(19-10-2015 22:36)]:98A943B0CB31457F521D]  Text1 text2 text3" | 
2
sed -r 's/^\[([[:digit:]]{1,})@.*\][[:space:]]+(.*)$/\1 \2/p;d'
3
49123456789004 Text1 text2 text3
4
5
$ echo "49123456789004@s.whatsapp.net(19-10-2015 22:36)]:98A943B0CB31457F521D]  Text1 text2 text3" | 
6
sed -r 's/^\[([[:digit:]]{1,})@.*\][[:space:]]+(.*)$/\1\2/p;d'
7
8
$ echo "[49123456789004x@s.whatsapp.net(19-10-2015 22:36)]:98A943B0CB31457F521D]  Text1 text2 text3" | 
9
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!

von Konrad S. (maybee)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.