perlunity.de - PERL | JAVASCRIPT | PHP | MySQL | APACHE



#!/COMMUNITY

Members: 5374
davon online: 1
weitere User: 19
Click for quality!




12.02.2012 / 04:11

Community-Member werden   |   Paßwort vergessen   |   OnlineMonitor (1) Wer ist online ... OnlineMonitor starten !
     

 

Home


PERLscripts


PHPscripts


JAVAscripts


Hilfreiches


Links2www


Newscenter


Community


Interna




Community  »  Perl: Allgemeines Forum zur Themenübersicht Themensuche Themenansicht in Thread-Modus


BeitragPerlanfä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

Beitragre: 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 -w

use 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

Beitragre: 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

Beitragre: 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

Beitragdas 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 -w

use 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

Beitragre: 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

Beitragre: 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

Beitragre: 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

Beitragre: 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

Beitragre: 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

Beitragre: 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

Beitragre: 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

Beitragre: 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

Beitragre: 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

Beitragre: 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 file

for(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

-






-
-