Thread Datei mit Tabstops umstrukturieren (11 answers)
Opened by roeschu at 2005-11-04 11:04

Dubu
 2005-11-04 13:10
#59704 #59704
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
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:
Code: (dl )
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:
Code: (dl )
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