Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]7401[/thread]

Auslesen aus .txt bis Trennzeichen, wie?: Auslesen aus .txt bis Trennzeichen, wie?



<< |< 1 2 3 4 ... 6 >| >> 52 Einträge, 6 Seiten
Gast Gast
 2005-10-26 14:09
#59343 #59343
Hallo zusammen,
hätte folgende Frage zum auslesen aus einer Textdatei:

Meine .txt sieht folgendermaßen aus:
"Name von Firma1";1234567;"08001234567";"12"
"Name von Firma22";123;"08001234589";""
"Name Firma3";12345;"080012343";"12"

Diese Textdatei möchte ich auslesen und formartiert in eine neue Textdatei schreiben. Jetzt stellt sich die Frage, wie ich perl sagen soll, dass es bis zum Strichpunkt einließt und das dann in einer Variable1 speichert. Dann die Zahl zwischen erstem und zweitem Strichpunkt einließt und in Variable2 speichert. Hab das schon mit substr probiert, geht aber glaub ich nicht, weil die Einträge ja immer unterschiedlich lang sind. Wenn ich die Variablen hätte könnte ich die Inhalte schön bearbeiten, das ganze in ein Array schreiben und dann ich in eine neue Textdatei.

Vielen Dank schonmal im Voraus
duerov
Ronnie
 2005-10-26 14:22
#59344 #59344
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
verwende split und schreibe es direkt in ein Array.

EDIT:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

while (<DATA>) {
chomp;
my @row = split /;/, $_;
@row = map { s/"//g; $_ } @row;
print Dumper \@row;
}

_ _DATA_ _
"Name von Firma1";1234567;"08001234567";"12"
"Name von Firma22";123;"08001234589";""
"Name Firma3";12345;"080012343";"12"
\n\n

<!--EDIT|Ronnie|1130322588-->
AndreasM
 2005-10-26 14:30
#59345 #59345
User since
2005-10-08
31 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo,
Ich hatte mal sowas, um Tabulatorgetrennte Dateien in eine Excel-Datei zu schreiben.
Im Prinzip hast Du das gleiche Problem.
Das hier ist nur ein Beispiel, und bitte bedenke: Ich bin auch Neuling :)
Das Beispiel nimmt an, dass Deine Eingabedatei Semikolon getrennt ist, und Deine Ausgabedatei tabulatorgetrennt:
--schnipp
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
foreach my $TABDATEI (glob("*.txt")){
  open (EINGABEFILE, "<$TABDATEI") or warn "Kann $TABDATEI nicht lesen!\n";
  open (AUSGABEFILE, ">$TABDATEI.neu.txt");
   while (<EINGABEFILE>) {
       chomp;
       # Split on single tab
       my @Fld = split(';', $_);

       foreach my $token (@Fld) {
           print AUSGABEFILE "$token\t"
           }
       print AUSGABEFILE "\n";
       }
 }

--schnipp--

Das hier ist der Code von meinem, äh, TabToExcel-Skript. Vielleicht hilft es Dir was.

--schnipp--
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
#! D:\Perl\bin

use Spreadsheet::WriteExcel::Big; # ben÷tigt IO::Stringy and OLE::Storage_Lite

my $Dateiendung=$ARGV[0];
unless (defined($Dateiendung)){
   print "Bitte Dateiendung angeben: ";
   chop($Dateiendung = <STDIN>);}

unless (defined (my $filename = glob("*.$Dateiendung"))){
   warn "Keine Datei zu verarbeiten!\nScript wird beendet.\n";
   sleep 5;
   die;}
#Ende der &▄berpr³fung

$Dateiendung=~ m/([a-z_0-9]+$)/i;
foreach my $TABDATEI (glob("*.$1")){
   my $SHEETCOUNTER = 1;
   $TABDATEI=~ m/(^[^.]+)/i;
   print "verarbeite $TABDATEI\n";
   open (TABFILE, "<$TABDATEI") or warn "Kann $TABDATEI nicht lesen!\n";
   # Create a new Excel workbook
   my $workbook = Spreadsheet::WriteExcel::Big->new("$1.xls");
   my $worksheet = $workbook->add_worksheet();   # Sheet1

   # Row and column are zero indexed
   my $row = 0;

   while (<TABFILE>) {
       chomp;
       # Split on single tab
       my @Fld = split('\t', $_);

       my $col = 0;
       foreach my $token (@Fld) {
           $worksheet->write_string($row, $col, "$token");
           $col++;
           if ($col > 255) {
               warn ("Fehler! Maximale Spaltenzahl ³berschritten!\nScript wird beendet");
               <>;
               die;}
       }
       print STDOUT ("Arbeitsblatt $SHEETCOUNTER, Zeile $row\n");
       $row++;
       if ($row > 65535) {
           $row = 0;
           $SHEETCOUNTER++;
           $worksheet = $workbook->add_worksheet();
           }
   }
$workbook->close();
close TABFILE;}


exit;

--schnipp--

Grüße
AndreasM\n\n

<!--EDIT|renee|1130328238-->
master
 2005-10-26 15:23
#59346 #59346
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
Ok hier mein Beispiel:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
open(DATEI, "<daten.txt") or die $!;
while (<DATEI>)
{
 $tmp = $_;
 $tmp =~ s/\"//gis;  # Diese Zeile Entfernt alle "
 my @Daten = split(';', $tmp);  #Im Array @Daten sind jetzt alle Felder der aktuellen Zeile.
 
# Zugriff auf ein Element der Aktuellen Zeile ==>  $Daten[1]  
# Du kannst jetzt gleich in diesem schritt bearbeiten
# und durch ">>" anhängen Zeilenweise in eine neue Datei schreiben.
}
close(DATEI);
\n\n

<!--EDIT|master|1130325859-->
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
AndreasM
 2005-10-26 15:41
#59347 #59347
User since
2005-10-08
31 Artikel
BenutzerIn
[Homepage] [default_avatar]
@master

Ist es denn sinvoll, prinzipiell ALLE " zu entfernen? Meiner Ansicht nach sollte man sich auf " zu Beginn und am Ende eines Feldes beschränken (wenn beides gegeben ist, denn nur dann sind sie als textbegrenzungszeichen zu werten). Es kann ja auch sein (ist bei uns in der Firma oft so), das es keine Textbegrenzungen, sondern "gewünschte" Hervorhebungen sind :)

MfG
AndreasM
master
 2005-10-26 15:58
#59348 #59348
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
Naja die DB sollte schon sinvoll aufgebaut sein.

Code: (dl )
"Name """Firma3";12345;"080012343";"12"

Da bekommt man schon Mühe...
Ansonsten lässt sichst nur duch ein besseren Regulären Ausdruck lösen..

ich denke aber das die "" beim obigen Problem
hier teils als überflüssige felderbegrenzugen benutzt wurden.

eigentlich würde nur ; reichen... ich habe früher oft mit TXT-Dateien auf diese art und weise gearbeitet..
\n und ; reichen eigentlich vollkommen aus...\n\n

<!--EDIT|master|1130328017-->
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
renee
 2005-10-26 16:06
#59349 #59349
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Es handelt sich ja offenbar um eine CSV Datei. Dafuer gibt es ganz gute Module auf CPAN z.B. CPAN:Text::CSV oder CPAN:DBD::CSV. Die behandeln schon alle moeglichen Besonderheiten, an man selbst haeufig nicht denkt...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Dubu
 2005-10-26 16:14
#59350 #59350
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Die bisherigen Ansätze streichen alle die Segel, wenn eines der gequoteten Felder ein Semikolon enthält. Kann das passieren, duerov?


Da das Format nach CSV-Daten aussieht, wie AndreasM schon bemerkte, empfehle ich ein passendes Modul:
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
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;     # oder Text::CSV_XS, falls vorhanden

my $csv = Text::CSV->new({sep_char => ';'});

my @AlleZeilen;

while (my $zeile = <DATA>) {
   if ($csv->parse($zeile)) {
       push @AlleZeilen, [ $csv->fields() ];
   } else {
       die "kann Zeile nicht parsen: " . $csv->error_input();
   }
}
# Debug-Ausgabe
use Data::Dumper;
print Dumper \@AlleZeilen;

_ _DATA_ _
"Name von Firma1";1234567;"08001234567";"12"
"Name von Firma22";123;"08001234589";""
"Name Firma3";12345;"080012343";"12"
"Name Firma 4; Zusatz";234;"0800102030";""
"Name Firme ""Fünf"" ";987;"0900999999";"42"

(Bitte wie immer die Leerzeichen aus _ _DATA_ _ entfernen.)

Doppelte Anführungszeichen innerhalb eines Feldes, wie sie AndreasM angesprochen hat, werden bei CSV übrigens verdoppelt, womit Text::CSV und Text::CSV_XS auch zurecht kommen.
master
 2005-10-26 16:30
#59351 #59351
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
Quote
Doppelte Anführungszeichen innerhalb eines Feldes, wie sie AndreasM angesprochen hat, werden bei CSV übrigens verdoppelt, womit Text::CSV und Text::CSV_XS auch zurecht kommen


Eben genau das.. sie werden "markiert"
ohne markierung = problem..

und zwar muss das strenggenommen mit \n, ; und " passieren...

es sei denn man man verringert die anzahl der "Trennzeichen" von 3 auf 2.. was es leichter macht.

oder eben das Modul benutzen :-)
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
renee
 2005-10-26 16:39
#59352 #59352
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Und wie mit CPAN:DBI und CPAN:DBD::CSV gearbeitet wird zeigt dieser Wiki:Artikel.
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
<< |< 1 2 3 4 ... 6 >| >> 52 Einträge, 6 Seiten



View all threads created 2005-10-26 14:09.