Thread Datei mit Tabstops umstrukturieren
(11 answers)
Opened by
roeschu
at 2005-11-04 11:04
User since 2003-08-04
2145
Artikel
ModeratorIn + EditorIn
Ach so, incoming und outgoing. Sag das doch gleich ... ;)
Hier ist mal ein Ansatz, der nur mit Regexen arbeitet, ohne unpack(). Der einzige Trick hier ist, dass ich den INPUT_RECORD_SEPARATOR umgesetzt habe, um die Datensätze zu trennen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
#!/usr/bin/perl use strict; use warnings;
# Datensatztrenner beim Einlesen $/ = "\n\n--------";
while (<>) { # lokale Variablen my ($date, $time, $localphone, $remotephone, $duration) = (0,0,0,0,0);
# abgehender Anruf if (/OUTGOING CALL/) { # Datum, Uhrzeit und lokale Nummer merken if (/\A\s+(\d\d\/\d\d\/\d\d)\s+(\d\d:\d\d:\d\d)\s+LINE\s*=\s*\d+\s+STN\s*=\s*(\d+)/) { $date = $1; $time = $2; $localphone = $3; } else { warn "OUT: Kein Datum, Uhrzeit oder lokale Nummer in Datensatz:\n$_\n"; }
# Angerufene Nummer merken if (/\n\s+DIGITS DIALED\s+(\d+)/) { $remotephone = $1; } else { warn "OUT: Kein angerufene Nummer in Datensatz:\n$_\n"; }
# Anrufdauer merken if (/\n(\d\d:\d\d:\d\d)\s+CALL RELEASED/) { $duration = $1; } else { warn "OUT: Keine Anrufdauer in Datensatz:\n$_\n"; }
# Alles in einer Zeile ausgeben print "OUT,$date,$time,$localphone,$remotephone,$duration\n";
# eingehender Anruf } elsif (/INCOMING CALL/) { my $whatsnext = '---'; # noch eine lokale Variable
# Datum, Uhrzeit und lokale Nummer merken if (/\A\s+(\d\d\/\d\d\/\d\d)\s+(\d\d:\d\d:\d\d)\s+LINE\s*=\s*\d+\s+STN\s*=\s*(\d+)/) { $date = $1; $time = $2; $localphone = $3; } else { warn "IN: Kein Datum, Uhrzeit oder lokale Nummer in Datensatz:\n$_\n"; }
# Anrufende Nummer merken if (/\n\s+CALLING NUMBER\s+(\d+)/) { $remotephone = $1; } else { warn "IN: Kein anrufende Nummer in Datensatz:\n$_\n"; }
# Anrufdauer und Ergebnis merken # TODO: statt "HANG UP" sollte das stehen, was im Log auftaucht, # wenn der Anrufer auflegt, ohne angenommen worden zu sein. if (/\n(\d\d:\d\d:\d\d)\s+(CALL RELEASED|TRANSFERRED|HANG UP)/) { $duration = $1; $whatsnext = $2; } else { warn "IN: Keine Anrufdauer in Datensatz:\n$_\n"; }
# Alles in einer Zeile ausgeben print "IN,$date,$time,$localphone,$remotephone,$duration,$whatsnext\n";
} # alles andere ignorieren }
Mit deinen Daten sieht das Ergebnis so aus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
$ ./phonelog2csv.pl sonnemondesonnemondsonnemond > phone.csv IN: Kein anrufende Nummer in Datensatz: 10/27/05 10:07:31 LINE = 0241 STN = 2152 BC = SPEECH 00:00:00 INCOMING CALL RINGING 0:04 LINE = 0092 00:00:36 CALL RELEASED
-------- $ cat phone.csv IN,10/27/05,10:01:52,2152,0435487868,00:00:19,TRANSFERRED OUT,10/27/05,10:03:09,1101,0546878798,00:01:26 OUT,10/27/05,10:05:27,2116,0546878798,00:00:59 OUT,10/27/05,10:05:29,1101,0318786877,00:01:50 OUT,10/27/05,09:59:01,1135,0318786877,00:09:05 IN,10/27/05,10:07:31,2152,0,00:00:36,CALL RELEASED OUT,10/27/05,10:06:30,2116,054787878,00:02:22 IN,10/27/05,10:09:03,2105,079878787,00:00:48,CALL RELEASED IN,10/27/05,10:02:04,1146,0313133131,00:07:47,CALL RELEASED $
Die Warnmeldung erscheint, wie man sieht, nur auf STDERR, sodass sie bei einer Umleitung der Ausgabe wie oben nicht mit umgeleitet wird.
Das Skript behandelt so nur eingehende und ausgehende, aber keine weitergeleiteten Anrufe. Aber vielleicht kannst du darauf aufbauen. Man koennte es auch noch etwas schoener machen, dass nicht gleiche Teile (z.B. fuer Datum/Uhrzeit/lokale Nummer) mehrfach auftauchen.
View full thread Datei mit Tabstops umstrukturieren
|