ubuntuusers.de

Von AWK zu Perl - Teil 3: wo ist die Funktion...

Status: Gelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

oliver1804

Anmeldungsdatum:
27. März 2006

Beiträge: 279

Wohnort: Elmshorn

Hallo,

in gawk gibt es die Funktion gensub(), mittels derer ich aus einem String/einer Variable heraus durch Angabe von Regex Ersetzungen durchführen kann, die sich nicht auf den Ausgangsstring auswirken, sondern lediglich den auf dem Ausgangsstring basierenden Ergebnisstring bestimmen.

Gibt's sowas auch was in Perl?

FLoH.tar

Anmeldungsdatum:
6. Januar 2006

Beiträge: 470

hi,

direkt nicht, aber: (my $modified = $original) =~ s/...

– FLoH.tar

oliver1804

(Themenstarter)

Anmeldungsdatum:
27. März 2006

Beiträge: 279

Wohnort: Elmshorn

@FLoH.tar et al

wahrscheinlich ist mein Weg nicht richtig:

ich möchte auf eine .dbf-Datei (Clipper,dbase) zugreifen, um die Daten in einem 1. Schritt per SELECT * FROM DATEI ausgeben zu können.

Bisher hab ich dafür aus awk mittels Konsolenprogramm "odbc" (http://www.spinellis.gr/sw/outwit/) einfach über den eingebauten odbc-Treiber auf die .dbf zugegriffen.

Ein Aufruf sieht bspw. folgendermaßen aus:

odbc "Driver={Microsoft dBase-Treiber (*.dbf)};DBQ=D:\home\op\Eigene Jobs\tneu\SRC\BEFO" "SELECT * FROM KUST"

Nun hab ich versucht, das in Perl zu realisieren; hier mal der Code zur freundlichen Begutachtung 😉:

 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
#!perl
use warnings;
use strict;

use File::Copy;

use Win32::ODBC; # für eine ODBC-Verbindung mit KUST.DBF

# Netzverzeichnisvariablen
my $stammvz = "D:/home/op/Eigene Jobs/tneu/BEFODAT/"; # BEFO-QuellVerzeichnis

# Netzdateivariablen
my @kustfiles = qw/ KUST.DBF KUST2.DBF /;

# lokale Verzeichnisvariablen
my $maindir   = "D:/home/op/Eigene Jobs/tneu/"; # lokales Hauptverzeichnis
my $befolocal = $maindir . "SRC/BEFO/"; # BEFO-ZielVerzeichnis
my $gps       = $maindir . "SRC/GPS/"; # GPS-ZielVerzeichnis

# BEFO-Quelldateien nach lokal kopieren
foreach (@kustfiles) {
	copy($stammvz . $_, $befolocal)
		or warn "Kopieren von $_ fehlgeschlagen: $!";
}

# Verbindung mit KUST

my $dbpfad = "D:/home/op/Eigene Jobs/tneu/SRC/BEFO";
my $DSN = "Driver={Microsoft dBase-Treiber (*.dbf)};DBQ=$dbpfad";
my $db;
if (!($db = new Win32::ODBC($DSN))){
    print "Error connecting to $DSN\n";
    print "Error: " . Win32::ODBC::Error() . "\n";
    exit;
}
my $SqlStatement = "SELECT * FROM KUST";
if ($db->Sql($SqlStatement)){
    print "SQL failed.\n";
    print "Error: " . $db->Error() . "\n";
    $db->Close();
    exit;
}

my %Data;

while($db->FetchRow()){
    undef %Data;
    %Data = $db->DataHash();
    print $_;
}

$db->Close();

Ausgabe ist: Use of uninitialized value $_ in print at first.pl line 49.

Ab Zeile 28 kapier ich die Sache nur noch schemenhaft, da ich natürlich alles per copy & paste gemacht hab.

Würd mich freuen, wenn mir jemand aus der Klemme helfen könnte.

FLoH.tar

Anmeldungsdatum:
6. Januar 2006

Beiträge: 470

Sieht so aus, dass DataHash das globale $_ auf undef setzt. Die while-Schleife am Ende sollte sich so runterkürzen bzw. robuster gestalten lassen und tut immer noch das gleiche. Ist aber nicht getestet, probiers mal aus:

#my %Data; <-- nicht hier

while(my $row = $db->FetchRow()){
    my %Data = $db->DataHash(); # wozu? %Data wird hier nirgends verwendet.
    print $row;
}

oliver1804

(Themenstarter)

Anmeldungsdatum:
27. März 2006

Beiträge: 279

Wohnort: Elmshorn

@FLoH.tar

o.k., das war ein Fortschritt 😉:

D:\home\op\Eigene Jobs\tneu\scipts>perl -w first.pl 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111

EDIT: das steht natürlich nicht in den Feldern

FLoH.tar

Anmeldungsdatum:
6. Januar 2006

Beiträge: 470

Hab gerade mal in die Doku von Win32::ODBC geschaut, aber die ist auch für die Katz. Vermute aber, dass &DataHash eine Methode von $row ist, nicht von $db.

while (my $row = $db->FetchRow()){
    my %Data = $row->DataHash();

    # was auch immer du jetzt mit %Data machen willst, etwa
    while (my ($field,$value) = each %Data) {
        print "$field: $value\n";
    }
    print "======== \# Look, a new record haaaas beguunnn...\n";

}

Wo du deinen Code bloß her hast ...

oliver1804

(Themenstarter)

Anmeldungsdatum:
27. März 2006

Beiträge: 279

Wohnort: Elmshorn

@FLoH.tar

oh, wir haben - äh Du hast die ganzen 1er weggemacht 😢

D:\home\op\Eigene Jobs\tneu\scipts>perl first.pl Can't call method "DataHash" without a package or object reference at first.pl l ine 47.

FLoH.tar

Anmeldungsdatum:
6. Januar 2006

Beiträge: 470

$self->end_of($latin); # ☹

oliver1804

(Themenstarter)

Anmeldungsdatum:
27. März 2006

Beiträge: 279

Wohnort: Elmshorn

@FLoH.tar o.k., is spät - ich geh dann mal an der Matratze horchen und hoff, daß sich da bis morgen noch ein Experde findet.

Trotzdem: vielen Dank für die Mühe, vielleicht hab ich irgendwann auch mal soviel Durchblick, daß ich so ein Problem zumindest angehen kann. Momentan tut sich da bei mir leider nur ein riesiges Feld von Fragezeichen auf.

oliver1804

(Themenstarter)

Anmeldungsdatum:
27. März 2006

Beiträge: 279

Wohnort: Elmshorn

@FLoH.tar

Hier nun mal die funktionierende Lösung - ist zwar nicht, was ich letztlich will, aber ein Schritt in die richtige Richtung. Die Sache mit dem Bindungsoperator hab ich eingebaut; gegenüber gawk mit gensub() zwar etwas gewöhnungsbedürftig, aber mit 'nem Bißchen Übung merk ich das nach einiger Zeit nicht mehr.

Was mir bei Perl gefällt ist die Möglichkeit, daß man Variablen (Skalar,Array,Hash), sofern man mit der Notation vertraut ist, sofort erkennen kann. Das ist bei (g)awk leider nicht machbar.

 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
#!perl
use warnings;
use strict;

use File::Copy;

use Win32::ODBC; # für eine ODBC-Verbindung mit KUST.DBF

# Netzverzeichnisvariablen
my $stammvz = "D:/home/op/Eigene Jobs/tneu/BEFODAT/"; # BEFO-QuellVerzeichnis

# Netzdateivariablen
my @kustfiles = qw/ KUST.DBF KUST2.DBF /;

# lokale Verzeichnisvariablen
my $maindir   = "D:/home/op/Eigene Jobs/tneu/"; # lokales Hauptverzeichnis
my $befolocal = $maindir . "SRC/BEFO/"; # BEFO-ZielVerzeichnis
my $gps       = $maindir . "SRC/GPS/"; # GPS-ZielVerzeichnis

# BEFO-Quelldateien nach lokal kopieren
foreach (@kustfiles) {
	copy($stammvz . $_, $befolocal)
		or warn "Kopieren von $_ fehlgeschlagen: $!";
}

# Verbindung mit KUST

(my $dbpfad = $befolocal) =~ s/\/$//;
my $DSN = "Driver={Microsoft dBase-Treiber (*.dbf)};DBQ=$dbpfad";
my $db;
if (!($db = new Win32::ODBC($DSN))){
    print "Error connecting to $DSN\n";
    print "Error: " . Win32::ODBC::Error() . "\n";
    exit;
}

my $SqlStatement = "SELECT * FROM KUST";
$db->Sql($SqlStatement);

while ($db->FetchRow()) {
	undef my %Daten;
	%Daten = $db->DataHash();

	foreach (sort keys %Daten) {
		print $_, '=', $Daten{$_}, "\n";
	}
}

$db->Close();

FLoH.tar

Anmeldungsdatum:
6. Januar 2006

Beiträge: 470

Hm, undef my %Daten? Meines Wissens ist das undef hier redundant, da my schon von selbst eine undefinierte Variable deklariert. Aber wenn es funktioniert, ist ja alles gut 😉.

oliver1804

(Themenstarter)

Anmeldungsdatum:
27. März 2006

Beiträge: 279

Wohnort: Elmshorn

@FLoH.tar da ich das nur mehr oder weniger hirnlos per copy & paste abgekupfert habe, hab ich mir über Redundanz keine Gedanken gemacht, sondern nur, daß ich's in der Form "my %Daten = undef" geschrieben hätte; hab das undef nach 'nem Vergleich der beiden Ausgaben (identisch) nun aber rausgenommen.

thx

Antworten |