Perlanfänger
|
Seitenanfang |
Hallöle, könntet ihr mir bitte helfen ? Ich bin noch ein Perlanfänger und brauche hilfe. Hab das Bsp gefunden und weiss leider nicht wie ich das vervollständigen soll. 1. Wenn Unterordner existieren, ja es existieren unterordner... 2. Hier würde dann dein Porgrammcode zum Kopieren stehen Wie 3. Natürlich auch die Kontrolle, ob die Datei schon existiert Wie soll der check funktionieren. ??Könntet ihr mal das so vervollständigen das ich es mal Probieren kann bzw. dann bisschen rumspielen und ändern kann. Dann müsste ich es schaffen. Sonst frage ich euch . Danke euch im vorraus #! /usr/bin/perl -w # Variablen für die Verzeichnisse $quelle = "verzeichnis"; $ziel = "verz2"; Verzeichnis_lesen($quelle); Verzeichnis_bearbeiten(); # Wenn es einen Unterordner gibt geht es hier weiter if (@unterordner) { # Hier geht das Spiel wieder von Vorne los } # Einlesen der Einträge aus dem Quellverzeichnis sub Verzeichnis_lesen { my $quelle = $_[0]; opendir (ORDNER, $quelle) || die ("Konnte Verzeichnis \"$quelle\" nicht lesen: $!"); @ordner = readdir ORDNER; closedir ORDNER; } # Jeder Eintrag im Ordner wird einzelnen bearbeitet. # Dabei wird getestet, ob es sich um ein Verzeichnis oder eine Datei handelt # Dateien werden kopiert # Verzeichnisse werden in den Array @unterordner abgelegt und dabei schon als kompletter Pfad angelegt. sub Verzeichnis_bearbeiten { foreach (@ordner) { $pfad = "$quelle\/$_"; unless (-d $pfad) { # Hier würde dann dein Porgrammcode zum Kopieren stehen # Natürlich auch die Kontrolle, ob die Datei schon existiert print "- $_\n"; } else { my $pfad = "$quelle\/$_"; push @unterordner, $pfad; } } }
Datum: 17.10.2005-14:17

|
re: Perlanfänger
|
Seitenanfang |
Hi, falls Du dann die Files in jedem Unterverzeichnis ebenfalls kopieren willst, brauchst Du eine rekursive Funktion (also eine, die sich selbst aufruft). #! /usr/bin/perl -wuse strict; # sollte man sich angewöhnen, hilft wirklich! # Variablen für die Verzeichnisse my $quelle = "testdir"; my $ziel = "testdir2"; rekursiv_kopieren($quelle); sub rekursiv_kopieren { my $pfad = $_[0]; print "Verzeichnis: $pfad\n"; opendir (ORDNER, $pfad) || die ("Konnte Verzeichnis \"$pfad\" nicht lesen: $!"); my @ordner = readdir ORDNER; closedir ORDNER; foreach (@ordner) { next if /^\.\.?$/; # die Ordner . und .. ignorieren if ( -d "$pfad/$_" ) { rekursiv_kopieren("$pfad/$_"); # neu aufrufen, falls es sich um ein Verzeichnis handelt } else { # Hier würde dann dein Porgrammcode zum Kopieren stehen # Natürlich auch die Kontrolle, ob die Datei schon existiert print "\tDatei: $pfad/$_\n"; } } closedir ORDNER; }
Besser geeignet hierfür ist allerdings das Modul File::Find, welches zu den Standardmodulen gehört und bei jedem Perl dabei ist. Natürlich lernst Du dabei weniger über das "Innenleben", aber mehr darüber, das Rad nicht neu zu erfinden ;-) Gruss, svenXY
Datum: 17.10.2005-14:49

|
re: Perlanfänger
|
Seitenanfang |
| Hallo, und wie mache ich die Zeilen bzw. wie sieht der Code hier aus .. ....else { # Hier würde dann dein Porgrammcode zum Kopieren stehen # Natürlich auch die Kontrolle, ob die Datei schon existiert print "\tDatei: $pfad/$_\n"; } Danke nochmal im vorraus
Datum: 17.10.2005-16:00

|
re: das eigentliche kopieren
|
Seitenanfang |
use File::Basename; use File::Copy;... $filename = basename($file); if ( -f "$ziel/$filename" ) { print "$ziel/$filename existiert bereits\n"; } else { print "Need to copy: $file\n"; copy $file,"$ziel/filename" or warn "Could not copy: " $!; } }
Datum: 17.10.2005-16:13

|
das gleiche mit Find::File
|
Seitenanfang |
| Das geniale daran ist, dass es (zumindest für Linux) das Programm find2perl gibt, mit dem sich ganz einfach ein Gerüst bauen lässt. Ich habe nur
find2perl -type f (-type f für files) eingegeben, dann hat mir das Programm das Gerüst ausgespuckt, das ich dann nur angepasst habe:
#! /usr/bin/perl -wuse strict; use File::Find (); # Variablen für die Verzeichnisse my $quelle = "testdir"; my $ziel = "testdir2"; # Set the variable $File::Find::dont_use_nlink if you're using AFS, # since AFS cheats. # for the convenience of &wanted calls, including -eval statements: use vars qw/*name *dir *prune/; *name = *File::Find::name; *dir = *File::Find::dir; *prune = *File::Find::prune; sub wanted; # Traverse desired filesystems File::Find::find({wanted => \&wanted}, $quelle); exit; sub wanted { my ($dev,$ino,$mode,$nlink,$uid,$gid); (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _ && copy_file($name); } sub copy_file { my ($file) = @_; if ( -f "$ziel/$file" ) { print "$ziel/$file existiert bereits\n"; } else { print "Need to copy: $file\n"; } }
Datum: 17.10.2005-16:05

|
re: das gleiche mit Find::File
|
Seitenanfang |
| Hallo, ich habs versucht, und einiges geändert klappt jetzt ... ich komm in fahrt danke nochmal
Datum: 18.10.2005-13:19

|
re: Perlanfänger Fragen zu mkpath
|
Seitenanfang |
| Hallo Sven, hast recht, leider hab ich das nicht gewusst. Dir Frage wäre wie kann ich mit mkpath ordner anlegen und prüfen ob sie schon existieren, wenn sie existieren dann nicht mehr anlegen ? Wo muss ich das im Code hin ? Das wäre es dann für diese Woche ? Danke open(CMD," $cmd |") or die "can't open $cmd: $!"; my @output = <CMD>; close(CMD); rekursiv_kopieren($quelle); sub rekursiv_kopieren{ my $pfad = $_[0]; print "\nVerzeichnis: $pfad\n"; opendir (ORDNER, $pfad) || die ("Konnte Verzeichnis \"$pfad\" nicht lesen: $!"); my @ordner = readdir ORDNER; closedir ORDNER; foreach (@ordner) { next if /^\.\.?$/; if (-d "$pfad/$_"){ rekursiv_kopieren("$pfad/$_"); } else { my $Data = ( $_ =~ m/^.*\\(.*)$/ ); copy("$pfad/$_","$ziel/$_") or warn "can't copy $pfad/$_: $!"; #chmod - Datei-/Verzeichnisrechte ändern chmod(0750, "$ziel/$Data"); print "\tDatei $Data: $_\n"; } } closedir ORDNER; } Danke dir Sven nochmal BYE
Datum: 21.10.2005-10:44

|
re: Perlanfänger Fragen zu mkpath
|
Seitenanfang |
ich fürchte, ich verstehe nicht ganz... Du willst die ganze Ordnerstruktur 1:1 woandershin kopieren? Oder was kapiere ich da nicht?svenXY
Datum: 21.10.2005-10:59

|
re: Perlanfänger Fragen zu mkpath
|
Seitenanfang |
| Hallo Sven, nein wenn ich kopiere und in einem Verzeichniss 2 gleichnamige Dateien sind dan Kopiert er mir nur eine. Ich will das er mit mkpath die Verzeichnisse anlegt und dann kopiert. Also können gleiche Dateien in verschiedenen Verzeichnissen existieren. Sorry
Datum: 21.10.2005-11:09

|
re: Perlanfänger Fragen zu mkpath
|
Seitenanfang |
| wie sollen in einem Verzeichnis zwei gleichnamige Dateien liegen? Um das Ganze etwas verständlicher zu machen, könntest Du mal eine Struktur skizzieren, so a la dir1 - dir11 - dir12 - dir121 - file121 - file11 - file12 ... sonst verstehe ich echt nicht woran es hängt
Datum: 21.10.2005-11:13

|
re: Perlanfänger Fragen zu mkpath
|
Seitenanfang |
| Hallo, Verz1: a.txt , b.txt , c.txt Unterverz.1: a.txt x.txt Unterverz.2: b.txt y.txt Unterverz.3: c.txt , z.txt usw. Bei mir schreibt das Programm alles in einem Verzeichnis und tut kein Unterverzeichnis erstellen also werden die gleichnahmigen Dateien gelöscht. Muss mit mkpath irgendwie es hinbekommen das er vor dem kopieren nachschaut ob das Verzeichnis existiert und dann schreiben sonst eins erstellen. Danke
Datum: 21.10.2005-11:38

|
re: Perlanfänger Fragen zu mkpath
|
Seitenanfang |
| so wie ich Dich verstehe, willst Du alle Dateien von Quelle nach Ziel kopieren und zwar jeweils inklusive der Unterordner und den Dateien in ihnen. Da reicht doch einfach ein rekursives kopieren, dazu braucht man kein Perl...
Datum: 21.10.2005-11:47

|
re: Perlanfänger Fragen zu mkpath
|
Seitenanfang |
| also, ein paar Informationen, dann solltest Du es selbst hinkriegen: - mkpath gibt es - soweit ich weiss - nicht aber Du kannst ein Verzeichnis anlegen, wenn es noch nicht existiert mit fogendem Konstrukt: if (! -e $etwas && ! -d $etwas ) { # es ist kein directory und existiert nicht mkdir($etwas); }
Datum: 21.10.2005-11:33

|
re: Perlanfänger Fragen zu mkpath
|
Seitenanfang |
| Hallo, das hat geklappt :-) Danke Noch ein kleines Problem... Beim File bzw. open open(FILE,">text.txt"); #ein file for(1, 15803) { open(FILE,">text_$_.txt"); #viele files print FILE "$_\n"; close(FILE); } close(FILE); Was mache ich da falsch das funktioniert nicht. Ich will alle Dateien von einzeln vo 1 bis 15803 in eine Datei reinschreiben. Warum klappt das nicht .. Wenn das heute noch klappen würde wäre super.. Danke im vorraus.. BYE
Datum: 21.10.2005-15:56

|
re: Perlanfänger Fragen zu mkpath
|
Seitenanfang |
Hi, gut, dass Du vorankommst ;-)Zu dem neuen Problem: Du öffnest das Filehandle FILE für Dein Ergebnisfile - gut. Dann öffnest Du das Filehandle namens FILE erneut - da liegt das Problem. Ausserdem musst Du die Ergebnisdatei im Append-Modus anhängen (mit >>), sonst schreibt er jedesmal die Datei neu mit genau dem Inhalt des gerade aktiven files. Zusätzlich musst Du die Datei auch lesen, um sie irgendwohin schreiben zu können (open macht das nicht). Das sieht dann so aus: open(DESTFILE,">>text.txt"); #ein filefor(1..15803) { open(SRCFILE,">text_$_.txt"); #viele files while (<SRCFILE>){ print FILE "$_\n"; close(SRCFILE); } close(FILE);
So würde es gehen. Wenn es nur darum geht, die Dateien aneinanderzuhängen, ist das aber nicht besonders effektiv (öffnen - lesen - schreiben) Such mal nach "concatenate files" in google, vielleicht findest Du da was performanteres (falls Zeit eine Rolle spielt) Schönes Wochenende, svenXY
Datum: 21.10.2005-16:48

|