Davids Interblag Gesammelte Werke.

12Feb/130

Perl: Rekursives Auflisten einer Ordnerhierarchie

NACHTRAG vom 12.02.2013:

Wow, ich habe zwar mehr als 4000 Clicks für diesen Beitrag, jedoch hat mir nie jemand gesagt, dass das Script schon lange nicht mehr funktioniert, da in PERL unter Windows die Aufrufe 'chdir()/fchdir()' nicht mehr unterstützt werden. Bevor Fragen auftauchen: ja, mir ist die alte Version ein wenig peinlich. Aber bitte - bei der Erstellung der ersten Version war ich gerade 16; bei der Überarbeitung zarte 18 Jahre alt.

Inhaltsverzeichnis:

  1. Neue Version
  2. Neue Version: Sourcecode
  3. Alte Version
  4. Alte Version: Sourcecode

Neue Version

Diese neue Version, vom Februar 2013, funktioniert zwar anders als die ursprüngliche Version, erfüllt aber ihren Zweck: sie speichert alle Unterverzeichnisse und darin enthaltenen Dateien rekursiv in einer Textdatei. Inspiriert hiervorn. Der Aufruf geht z.B. folgendermaßen:

dir_bot.pl Documents

Nachtrag: Wuhu! use strict;!

Neue Version: Sourcecode


#!/usr/bin/perl -w
use strict;

my $base_path = shift;
if (!defined($base_path) || $base_path eq '') { die "You need to specify a directory (e.g. 'dir_bot.pl subfolder')!\n"; }

open(FILE,'>'.$base_path.'.txt') or die "Unable to create output: $!\n";
process_files ($base_path);
close(FILE);

print "Wrote output to: $base_path.txt\n";

sub process_files {
    my $path = shift;

    opendir (DIR, $path) or die "Unable to open $path: $!\n";
    
    # the dot at the end of the line is optional. I just use it for later parsing.
    print FILE "\t"x&get_slashes()."$path/.\n";
    my @files = grep { !/^\.{1,2}$/ } readdir (DIR);
    closedir (DIR);

    @files = map { $path . '/' . $_ } @files;

    for (@files) {
        if (-d $_) {
            process_files ($_);
        } else {
	    print FILE "\t"x&get_slashes()."$_\n";
        }
    }
}

sub get_slashes
{
if (defined $_)
{
return ($_ =~ tr/\///);
}
}

Alte Version

(Original published 28. Feb 2009)

Folgender Dirty-Snippet von 2005/2007 listet alle Unterordner und Dateien eines ausgewählten Ordners aus und speichert die Verzeichnisstruktur und Dateigrößen in einer Textdatei. Empfehlenswert für das Archivieren von großen Musik- oder Filmsammlungen.

Alte Version: Sourcecode


# Open Source dir-bot
# Copyright : David Kirberich

# SUBROUTINE NR.1 :

print "Directory Bot 0.2 Beta\n";
print "Copyright : David Kirberich, 2007\n";

sub Round ($ $) {
my ($num, $len) = @_;
$len = 0 unless defined $len;
my $add = $num >= 0 ? +0.5 : -0.5;
my $rounded = int($num * 10**$len + $add) / 10**$len;
return $rounded;
}

# SUBROUTINE NR.2 :

sub RecDirs {
$a = shift;
$i = shift;
$j = 0;

opendir(DIR,$a);
my @dir = readdir(DIR);
closedir(DIR);

chdir($a);

foreach $b (@dir) {
if (($b ne ".") && ($b ne "..")) {
if (-d $b) {

$i++;
$tt = "";
for($z = 0; $z <= $i; $z++) {
$tt = $tt."	";
}

push(@AUSGABE,$tt."[$b]");
RecDirs($b,$i);
chdir("..");
$i--;
} else {
if ($saf eq "1") {
$size = Round(((-s "$b")/1024/1024),2);
if ($size < 1) { $sizeB = "<1"; } else { $sizeB = $size; }
$i++;
$tt = "";
for($z = 0; $z <= $i; $z++) {
$tt = $tt."	";
}
push(@AUSGABE,$tt."$b - $sizeB MB");
$i--;
$p++;
$j=$j+$size;
$j2=$j2+$size;
}
}
}
}
if ($saf eq "1") {
push(@AUSGABE,$tt."Total : $j MB");
}
}

# START HAUPTPROGRAMM :

opendir(HOME,".");
my @home = readdir(HOME);
closedir(HOME);

$i = 0;
foreach $a (@home) { if (-e $a) { print "[$i] - $a\n"; $i++; }}
print "Please choose directory : ";
$dir = <stdin>;
print "\n";
chomp $dir;

print "Show all files ? (1/0) : ";
$saf = <stdin>;
print "\n";
chomp $saf;

for($j=0;$j<$i+1;$j++){if($j eq $dir){$locked=0;last;}else{$locked=1;}}
if ($locked == 0) {

opendir(DIR,@home[$dir]);
my @dir = readdir(DIR);
closedir(DIR);

$i = 0; # Dateien komplett
$j = 0; # Gr&amp;ouml;&amp;szlig;e komplett
$k = 0; # Ordner komplett
$l = 0; # Ordner im gesuchten Ordner
$p = 0; # Dateien im gesuchten Ordner
$t = "	"; # Trennzeichen
$tn = 0; # Inkrement f&amp;uuml;r Trennzeichen
$tt = ""; # Tempor&amp;auml;res Trennzeichen
chdir(@home[$dir]);

foreach $a (@dir) {
if (($a ne ".") &amp;&amp; ($a ne "..")) {
if (-d $a) { push(@ORDNER,$a); }
if (-f $a) { push(@DATEIEN,$a); }
}}


foreach $a (@ORDNER) {
push(@AUSGABE,"[$a]");
RecDirs($a,0);
chdir("..");
}

chdir(HOME);
chdir("..");
open(FILE,">@home[$dir].txt");
foreach $a (@AUSGABE) {
print FILE "$a\n";
}
if ($saf eq "1") {
print FILE "Total : $j2 MB\n";
}
close(FILE);

print "Logfile was saved as : \"@home[$dir].txt\".\n"; } else { print "Please try again.\n"; }

Kommentare (0) Trackbacks (0)

Zu diesem Artikel wurden noch keine Kommentare geschrieben.


Leave a comment

*

Noch keine Trackbacks.