Thread selektives File::Find (13 answers)
Opened by lichtkind at 2013-07-04 22:04

topeg
 2013-07-07 03:24
#168766 #168766
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Mal schnell und ungetestet
die kleine Funktion iterate_dirs nimmt zwei Codereferenzen und line Liste von Verzeichnissen.
Mit dem Ersten Code kann man entscheiden ob das Verzeichnis besucht werden soll, die zweite Referenz für jeden Eintrag im Verzeichnis ausgeführt. (bis auf "." und "..")
Das sollte flexibel und effizient sein.

Code (perl): (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
#!/usr/bin/perl
use strict;
use warnings;

my @files;
my @ignore=(
  '/usr/bin/',
  '/home',
);
iterate_dirs(
  # entscheiden ob das Verzeichnis besucht werden soll
  sub{
   for(@ignore)
   { return 0 if( index($_[1],$_)==0 ); }
   return 1 if( -r $_[0] );
   return 0;
  },

  # Auswerten des Eintrags
  sub{
    push(@files, $_[1]) if( -f $_[0] and -r $_[0] and substr($_[0],-4,4) eq '.pod' );
  },

  # die zu durchsuchenden Verzeichnisse
  '/usr/lib/perl5'
);

print "$_\n" for( @files );

#################################

sub iterate_dirs {
  my ($decide_code, $each_code, @stack ) =@_ ;

  my $dir=getcwd;

  my ($p,$dh,$path,$tmp);
  while(@stack)
  {
    $path = pop(@stack);
    chdir( $path ) or die "chdir($path) failed: $!";;
    opendir( $dh, '.' ) or die "Unable to open $path: $!\n";
    for( readdir( $dh ) )
    {
      next if( $_ eq '.' or $_ eq '..' );
      $tmp=$path.'/'.$_;
      push(@stack, $tmp) if( -d $_ and $decide_code->( $_, $tmp ) );
      $each_code->( $_, $tmp );
    }
    closedir ($dh);
  }

  chdir ( $dir ) or die "chdir($dir) failed: $!\n";
  return 1;
}


Nachteil ist natürlich das Links im FS einfach gefolgt werden. Der Code kann eventuell in einem ewigen Loop enden. Wollte man das beachten müsste man noch entsprechenden Code einbauen der Symbolische Links und echte erkennt, auflöst und sich merkt. Oder einfacher die Tiefe im Dateisystem begrenzen.

Sofern man bei Datei/Verzeichnis-Zugriffen Perl benutzt sollte das auch unter Windows, MacOS9 und co. funktioninieren, Da perl die Trenner wandelt.

View full thread selektives File::Find