• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Mit find ausschliessen von Verzeichnissen und Subdirectories

byron1778

Hacker
Hallo Forum!

Ich verwenden eine Solaris 10 Version und habe Probleme mit dem Verstehen bzw. Anwenden des find Befehles.

Ich wuerde gerne bestimmte Verzeichnisse ausschliessen bzw. nur einzelne Verzeichnisse, jedoch funktioniert es auf keine erdenkliche Art und Weise.

Folgendes habe ich mir dabei gedacht:

Ausschliessen von /var, ausser jedoch /var/log
Ausschliessen von /usr
Ausschliessen von /dev

Folgenden Code habe ich zuletzt versucht

Code:
find / -mtime 0 \( -print -name /var -prune -a -print -name /usr -prune -a -print -name /dev -prune \)

Leider funktioniert es ueberhaupt nicht und die Man - Page war auch keine allzugrosse Hilfe!

Kann mir jemand vll. ein wenig weiterhelfen?

Danke vielmals!
 
OP
B

byron1778

Hacker
Ich antworte mir einmal selber.
Dann, wenn man glaubt man schafft es nicht, sucht man um Hilfe an und startet noch einen letzten Versuch und ploetzlich schafft man es doch teilweise!

So, konnte ich einen Teil Mal loesen

Code:
find / -mtime -name var -prune -o -print -a -name usr -prune -o -print -a -name dev  -prune -o -print | more

Jetzt wuerde mich natuerlich interessieren, wie ich im Verzeichnis /var suchen kann und dabei aber gleich /var/sadm/* ausschliesse?
 

abgdf

Guru
Wenn der find-Befehl zu grob gestrickt sein sollte, mach's lieber in Perl mit "File::Find" (wobei Du "&File::Find::find()" mit "no_chdir => 1" aufrufen solltest).

Gruß
 

Escho

Advanced Hacker
so ein ähnliches Problem hatte ich auchmal: http://www.linux-club.de/viewtopic.php?f=21&t=100148

Edgar
 
OP
B

byron1778

Hacker
Hallo!

Danke Dir fuer Deinen Hinweis.
Tja, der find - Befehl ist zwar maechtig, aber kann leider auch nicht alles, oder fast nicht alles, zumindest unter Solaris ist es so.

Ich hab mir nun folgendes Konstrukt mit Perl zurecht gelegt, aber beim Iterieren habe ich nun Probleme!

So sieht es aus:

Code:
#!/bin/perl -w

%tree_of_not = (
        dev => {
                },
        devices => {
                },
        proc => {
                },
        etc => {
                nota => "/etc/orc",
                notb => "/etc/e2e",
                },
        );

while ( ($family, $roles) = each %tree_of_not ) {
    while ( ($role, $person) = each %$roles ) {
        $rc = system("find /$role -mtime 0 -print | grep -v -i $person >>/opt/find/log/find.log");
    }
}

Hier habe ich nun das Problem, dass das Programm leider zuerst die "Familie" durchlaeuft und erst dann die "Personen".
Ich braeuchte es aber anders, er soll die erste Familie durchlaufen, dann die dazugehoerigen Personen, dann die naechste Familie und wieder die dazugehoerigen Kinder, weil dann kann ich ohne Probleme die Familie und die Personen dem find - Befehl zuordnen und mittels grep ausschliessen!

Soll also so aussehen:

Code:
$rc = system("find /FAMILIE -mtime 0 -print | grep -v -i PERSON_DER_FAMILIE >>/opt/find/log/find.log");

Kann mir vll. jemand sagen, wie man das so durchlaufen kann?

Ich bekomme es leider nicht heraus!

Danke vielmals!
 
OP
B

byron1778

Hacker
So, das erste Problem haette ich geloest, aber leider noch nicht zur vollsten Zufriedenheit fuer mich.

Code:
#!/bin/perl -w

%tree_of_not = (
        dev => {
                nota => "fd",
                },
        devices => {
                nota => "pseudo",
                },
        etc => {
                nota => "orc",
                notb => "e2e",
                },
        opt => {
                nota => "netbeans",
                notb => "orc",
                notc => "gate",
                notd => "e2ereleases",
                notd => "orcbackup",
                },
        );

foreach $family(keys %tree_of_not) {

if ( exists $tree_of_not{$family}) {
                # you want to get the keys of the hash referred to
                # by $poems{$family}
                foreach $attribute(keys %{ $tree_of_not{$family} }) {
print "$family:      $tree_of_not{$family}{$attribute}\n";
#system("find \/$family -mtime 0 -print | grep -v -i $tree_of_not{$family}{$attribute} >>/opt/find/log/find.log");
}
                }
        }

Es besteht noch ein Problem, naemlich, wenn ich /opt/orc ausschliesse, es aber trotzdem vorkommt, dass er beim Durchlaufen von /opt/ /opt/orc anzeigt!
Es waere nun am besten, wenn ich anhand der Anzahl der Value Elemente mehrere grep -i -v grep einbaue!
Sprich: 4 Values sollen dann 4 greps ergeben.

Wie kann man so eine Abhaengigkeit erzeugen?

Weiss da jemand vll. eine Loesung?
 
OP
B

byron1778

Hacker
Hallo!

Ich habe das Problem nun etwas anders geloest, ist aber ueberhaupt nicht schoen, leider.
Falls jemand den Code schoener und sauberer hinbekommt, nehme ich gerne jede Hilfe an!

Code:
%tree_of_not_opt = (
        opt => {
                nota => "netbeans",
                notb => "orc",
                notc => "gate",
                notd => "e2ereleases",
                note => "orcbackup",
                },
        );

%tree_of_not_etc = (
        etc => {
                nota => "devices",
                notb => "e2e",
                notc => "saf",
                notd => "svc",
                note => "orc",
                },
        );


foreach $family_opt(sort keys %tree_of_not_opt) {
our $global_family_opt = $family_opt; # sonst wird die variable nicht sichtbar !!
        foreach $attribute_opt(keys %{ $tree_of_not_opt{$family_opt} }) {
                $i++;
$system_opt[$i] = " | grep -i -v $tree_of_not_opt{$family_opt}{$attribute_opt}";
#               print "$tree_of_not{$family_opt}{$attribute_opt}\n";
        }
}

foreach ($i) {
$string_opt = join("",@system_opt);
}
print "find /$global_family_opt -mtime 0 -print $string_opt\n";


## Second TREE

foreach $family_etc(sort keys %tree_of_not_etc) {
our $global_family_etc = $family_etc; # sonst wird die variable nicht sichtbar !!
        foreach $attribute_etc(keys %{ $tree_of_not_etc{$family_etc} }) {
                $i++;
$system_etc[$i] = " | grep -i -v $tree_of_not_etc{$family_etc}{$attribute_etc}";
#               print "$tree_of_not_etc{$family_etc}{$attribute_etc}\n";
        }
}

foreach ($i) {
$string_etc = join("",@system_etc);
}
print "find /$global_family_etc -mtime 0 -print $string_etc\n";
$rc = system("find /$global_family_etc -mtime 0 -print $string_etc >>/opt/find/log/find.log");
if ( $rc > 1 ) {
        print " irgendwas geht ned\n";
}
 

abgdf

Guru
Boah, ey!
ist aber ueberhaupt nicht schoen, leider.
Kann man wohl sagen! Dein Code oben ist schon eine Zumutung - für Dich und andere :mrgreen:.

Du solltest

- weniger kompliziert und verwinkelt denken: Wenn Du in Perl Hashes von Hashes benutzen willst, ist in aller Regel etwas nicht richtig,
- unbedingt "use warnings;" und "use strict;" verwenden,
- Dich mit "my" vertraut machen,
- bitte vier Leerzeichen pro Einrückung verwenden,
- Perl-Module anstatt system()-Calls verwenden.

Wenn schon mit 'system("find")' statt mit "File::Find" dann vielleicht für den ersten Teil z.B. einfach so:
Code:
my @a = qw(netbeans orc gate e2ereleases orcbackup);
my $b = "";
foreach (@a) {
    $b .= " | grep -i -v $_";
}
print "find /opt -mtime 0 -print$b\n";
Schon ein Unterschied, oder?

Gruß
 

abgdf

Guru
Oder noch kürzer:
Code:
print "find /opt -mtime 0 -print | grep -i -v " . join(" | grep -i -v ", qw(netbeans orc gate e2ereleases orcbackup)) . "\n";
:cool:

Gruß
 
OP
B

byron1778

Hacker
Hallo!

Danke Euch vielmals fuer Eure Tipps!
Ich konnte mein Programm ein wenig verkuerzen, schoener ist es,naja, nicht wirklich geworden, aber der Zweck heiligt vorerst einmal die Mittel ...
Ich muss nur mehr rausfinden, wie ich einen Hash referenzieren und dereferenzieren kann, das geht leider noch nicht

Code:
#!/bin/perl -w

%tree_of_not_opt = (
        opt => {
                nota => "netbeans",
                notb => "orc",
                notc => "gate",
                notd => "e2ereleases",
                note => "orcbackup",
                },
        );

%tree_of_not_etc = (
        etc => {
                nota => "devices",
                notb => "e2e",
                notc => "saf",
                notd => "svc",
                note => "orc",
                },
        );

$ref_of_opt = \%tree_of_not_opt; # Referenzierung
$ref_of_etc = \%tree_of_not_etc; # Referenzierung
@array = qw/$ref_of_opt $ref_of_etc/;

for ( $j=0; $j < @array; $j++ ) {
$ref = $array[$j];
[color=#FF0000][b]%tree_of_not_opt = $$ref; # Hier sollte die Dereferenzierung stattfinden ...[/b][/color]

foreach $family_opt(sort keys %tree_of_not_opt) {
our $global_family_opt = $family_opt; # sonst wird die variable nicht sichtbar !!
        foreach $attribute_opt(keys %{ $tree_of_not_opt{$family_opt} }) {
                $i++;
$system_opt[$i] = " | grep -i -v $tree_of_not_opt{$family_opt}{$attribute_opt}";
#               print "$tree_of_not{$family_opt}{$attribute_opt}\n";
        }
}

foreach ($i) {
$string_opt = join("",@system_opt);
}
print "find /$global_family_opt -mtime 0 -print $string_opt\n";
}
 
OP
B

byron1778

Hacker
Hi!

So, hab es nun soweit geschafft, einen Hash von einem Hash zu referenzieren und dereferenzieren.
Dafuer gibt er mir nun nur mehr das /opt aus und sonst nichts:

Code:
#!/bin/perl -w

%tree_of_not_opt = (
        opt => {
                nota => "netbeans",
                notb => "orc",
                notc => "gate",
                notd => "e2ereleases",
                note => "orcbackup",
                },
        );

%tree_of_not_etc = (
        etc => {
                nota => "devices",
                notb => "e2e",
                notc => "saf",
                notd => "svc",
                note => "orc",
                },
        );

@array_hash = (\%tree_of_not_opt, \%tree_of_not_etc);

for ( $j=0; $j <= 2 ; $j++ ) {
        $ref = $array_hash[$j];
        foreach $family_opt (keys(%{$ref})) {
                foreach $family_opt(sort keys %tree_of_not_opt) {
                                our $global_family_opt = $family_opt; # sonst wird die variable nicht sichtbar !!
                                print "global_family_opt: $global_family_opt\n";
                                foreach $attribute_opt(keys %{ $tree_of_not_opt{$family_opt} }) {
                                        $i++;
                                        $system_opt[$i] = " | grep -i -v $tree_of_not_opt{$family_opt}{$attribute_opt}";
#                                       print "$system_opt[$i]\n";
#                                       print "$tree_of_not{$family_opt}{$attribute_opt}\n";
                                }
                }
        }
}

foreach ($i) {
        $string_opt = join("",@system_opt);
        print "find /$global_family_opt -mtime 0 -print $string_opt\n";
}

Ausgabe:


  • global_family_opt: opt
    global_family_opt: opt
    Use of uninitialized value in join or string at ./endlich2.pl line 42.
    find /opt -mtime 0 -print | grep -i -v gate | grep -i -v orc | grep -i -v netbeans | grep -i -v orcbackup | grep -i -v e2ereleases | grep -i -v gate | grep -i -v orc | grep -i -v netbeans | grep -i -v orcbackup | grep -i -v e2ereleases

Irgendwie komme ich nicht hinter den Fehler in meinem Programm.
Letzten Endes habe ich ja "nur" eine for - Schleife drum herum gebaut und die Referenz darin dereferenziert!

Kann mir jemand vll. bemi letzten Schirtt helfen den Fehler wegzubekommen?

Danke Euch vielmals!
 

abgdf

Guru
hab es nun soweit geschafft, einen Hash von einem Hash zu referenzieren und dereferenzieren.
Was Du, wie gesagt, überhaupt nicht brauchst.

Läuft Dein Skript eigentlich mit "use strict;" ?
Das sollte es jedenfalls.

Gruß
 
OP
B

byron1778

Hacker
Hallo!

Dein Script funktioniert perfekt.
Eines wuerde mich interessieren: Du meintest, dass man Hashes von Hashes nicht verwenden sollte, bzw. bei Moeglichkeit nicht gebrauchen.
Gibt es einen naeheren Grund dafuer?
Zu langsam, umstaendlich?

Danke Dir vielmals!
 

abgdf

Guru
Hallo,
erstmal gut, wenn's geht!
Du meintest, dass man Hashes von Hashes nicht verwenden sollte, bzw. bei Moeglichkeit nicht gebrauchen. Gibt es einen naeheren Grund dafuer? Zu langsam, umstaendlich?
Ja, genau. Es besteht auch die Gefahr, sich damit zu verheddern. Je komplizierter eine Datenstruktur ist, desto schwerer ist sie auch zu handhaben. Was man dafür mindestens einmal durchgearbeitet haben sollte, wäre
Code:
perldoc perllol
Wenn sowas auftritt, würde ich schon eher ein eigenes Package oder eine Klasse definieren.
Das alles ist wie gesagt hier aber glücklicherweise nicht nötig.

Viele Grüße
 
Oben