Schrift
[thread]8999[/thread]

Verzeichnisssuche mit einem Perlscript



<< >> 5 Einträge, 1 Seite
Gast Gast
 2007-05-12 17:04
#76656 #76656
Hallo Leute,

ich habe folgendes Problem, ich möchte mit einem Skript nach Verzeichnissen suchen die entweder leer oder < 1MB sind.

Quasi so:
#perl search_empty.pl C:\test\

Ausgabe soll so aussehen:
C:\>perl dirzeigen.pl c:\test
aaa Size: 4.828253Mb, Files: 4, folders: 0
bbb Size: 4.828253Mb, Files: 4, folders: 0
ccc Size: 4.828253Mb, Files: 4, folders: 0
ddd Size: 4.828253Mb, Files: 4, folders: 0

so das ich mir dann nur noch >1 MB ausgeben lassen kann um diese zu entfernen.

Ich habe mir hierzu was zusammen gebastelt, aber ich komme leider nicht auf die gewünschte Ausgabe. (Eigentlich nur fehler meldungen :))


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 -w
use WIN32::Console;
use strict;
use warnings;
use File::Find::Rule ();

die 'usage: search_empty.pl *directory*'
unless 1 == @ARGV;

my @array = `dir /A:D /B @ARGV`;
for(my $i=0;$i<@array;$i++){
#print "$array[$i]";
my( $size, $files, $folders );
my $rule = File::Find::Rule-> start( @ARGV );

while( my $item= $rule->match )
{
next if $ARGV[0] eq $item;
$size+= -s $item;
-f $item and $files++;
-d $item and $folders++;
}

printf "$Size: %fMb , Files: %d, folders: %d\n"
=> $size / 1024**2, $files, $folders;
}


meine Idee war es denn $array mit dem unterverzeichnis einfach ans "@ARGV" zuhängen,
so das im @ARGV&$array --> c:\test\aaa steht und das dann in der schleife abgearbeitet wird.
Leider Kollediert meine Denkweise etwas mit Perl.

Wäre sehr Dankbar fuer einen kleinen Denkanstoss
gruss benjo
benjo
 2007-05-12 20:34
#76657 #76657
User since
2007-05-12
13 Artikel
BenutzerIn
[default_avatar]
Ich hab da noch was geändert weil ich gesehen habe das
ich mich in der schleife etwas verhädert habe, trotzdem immer
noch kein erfolg.

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 -w
use WIN32::Console;
use strict;
use warnings;
use File::Find::Rule();

die 'usage: dir_z_size.pl *directory*'
unless 1 == @ARGV;

my @array = `dir /A:D /B @ARGV`;
for(my $i=0;$i<@array;$i++){
my( $size, $files, $folders );
my $path = "$ARGV[0]"."$array[$i]";
print "$path";
my $rule = File::Find::Rule->start( $path );

while( my $item = $rule->match )
{
next if $path eq $item;
$size+= -s $item;
-f $item and $files++;
-d $item and $folders++;
}
printf "$path: $size: %fMb, Files: %d, folders: %d\n"
=> $size / 1024**2, $files, $folders;
}


Die Werte werden richtig übergeben und es werden auch richtig die Verzeichnisse gezogen und zu einem Pfad zusammen gesetzt
nur das:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
my $rule = File::Find::Rule->start( $path );

while( my $item = $rule->match )
{
next if $path eq $item;
$size+= -s $item;
-f $item and $files++;
-d $item and $folders++;
}
printf "$path: $size: %fMb, Files: %d, folders: %d\n"
=> $size / 1024**2, $files, $folders;


Funktioniert nicht richtig,... hat jemand rat ?

vielen Dank im Vorraus :benjo
PerlProfi
 2007-05-13 00:53
#76658 #76658
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Also das Modul File::Find::Rule kenne ich nicht, aber ich würde das mit opendir() anstelle des Systemaufrufs und File::Find erledigen:
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
#!/usr/bin/perl -w
use strict;
use File::Find;

# startverzeichnis holen
my $dir = shift() || '.';
print "Search in $dir...\n";

my $max = 8; # laenge des laengsten verzeichnisses

# startverzeichnis oeffnen
opendir(my$hDIR, $dir)
or die "Can't open directory '$dir': $!";

# unterverzeichnisse einlesen
my @content = grep {
# vollstaendigen pfad besorgen
my $f = "$dir/$_";

# auf verzeichnis pruefen ( . und .. auslassen )
if (-d $f && !/^\.\.?$/) {
# max. laenge eventuell neu setzen
$max = length($f) if length($f) > $max; 1
}
} readdir($hDIR);

# startverzeichnis schliessen
closedir($hDIR);

# durch die unterverzeichnisse iterieren
foreach my$item (@content) {
# variablen initialisieren
my($path, $size, $files, $folders) = ("$dir\/$item", 0, 0, 0);

# groesse, anzahl dateien und anzahl ordner ermitteln
find(sub { -f && ++$files; -d && !/^\.\.?$/ && ++$folders; $size += -s }, $path);

# groesse auf MB bringen
$size /= 1024**2;

# groesse in 2 stuecke aufteilen
my $s1 = int($size);
my $s2 = $size-$s1;
if (length($s2) > 2)
{ substr($s2, 0, 2) = '' }
else
{ $s2 = 0 }

# ausgabe
printf '%-'.$max.'s Size: %4d.%08.8sMb Files: %4d Folders: %4d %4s'."\n"
=> $path, $s1, $s2, $files, $folders, $size < 1 ? '<1MB' : '';
}

Leider ist mir gerade nicht mehr eingefallen wie man in einem Format definieren kann, dass ein float eine Konstante Länge vor dem Komma, sowie nach dem Komma besitzt, daher habe ich die Verzeichnisgröße aufgeteilt.
$max ist neben $s1 und $s2 auch nur für die hübsche Ausgabe zuständig.

MfG

edit: in der ausgabe ein überflüssiges $max entfernt und '.' als default verzeichnis festgelegt\n\n

<!--EDIT|PerlProfi|1179003473-->
benjo
 2007-05-13 14:58
#76659 #76659
User since
2007-05-12
13 Artikel
BenutzerIn
[default_avatar]
Super vielen Dank, hätte nicht erwartet schon gleich eine fertige lösung zu bekommen.
Da ich mich erst seit kurzem, um genau zu sein seit ca. 2 Tagen, mit Perl beschäftige, wo lag vom File::Find::Rule Modul abgesehen mein fehler ?

gruss benjo
PerlProfi
 2007-05-13 17:37
#76660 #76660
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Was bekommst du denn zurück ?
Kriegst du irgendwelche Fehlermeldungen ?

Ansonsten kannst du ja mal ein paar mehr Testausgaben rein bringen und schauen wie es dann aussieht.

MfG
<< >> 5 Einträge, 1 Seite



View all threads created 2007-05-12 17:04.