Christoph Schnauß: Betriebsblindheit oder ...?

hallo Forum ;-)

es könnte bemerkt worden sein, daß ich mich in den letzten Tagen bemühe, endlich richtig PERL zu lernen bzw. das, was ich mal vor langer Zeit gelernt habe, auf den angemessenen Stand zu bringen  -  insbesondere, was CGI.pm angeht.
Da habbich nun nochmal nen Problemchen. Folgendes will ich machen, um den Inhalt der Dateien in einem Verzeichnis in einen Array einzulesen und weiterzuverarbeiten:

opendir(VERZ,"$basedir") || die $!;
@inhalt = readdir(VERZ);
closedir(VERZ);
print $cgi->header().
      $cgi->start_html(-title =>'Verzeichnis auslesen', -style =>{'src'=>$css}).
      "\n";
foreach $zeile (@inhalt) {
   if ($zeile ne '.' && $zeile ne '..') {
      open(LISTE,"+<$basedir/$zeile") || die $!;
      @anzeige = <LISTE>;
      close(LISTE);
   }
   foreach $zeile_neu (@anzeige) {
   [tu irgendwas]
   }
}
print $cgi->end_html();

Nett, gelle? Funktioniert auch prima, egal was ich in [tu irgendwas] noch an Dutzenden von Codezeilen reinschubse  -  aber es funktioniert "zu gut". Ich habe in dem auszulesenden Verzeichnis etliche hundert *.htm-Dateien liegen, auf die es ankommt. Leider aber liegen auch noch ungefähr zehn *.txt-Dateien drin und zwei PHP-Scripts, und _die_ sollen nun nicht mit erfaßt werden. Ich müßte also meine Bedingung
   if ($zeile ne '.' && $zeile ne '..')
(die das Durchsuchen des übergeordneten Verzeichnisses unterbindet) noch irgendwie durch irgendein "elsif" ergänzen, mit dem auch die Dateien, die _nicht_ *.htm sind, von der Erfassung ausgeschlossen werden. Das sollte eigentlich fürchterlich leicht sein, aber ich hab mich wohl zu sehr darein verbissen, so daß ich grade nicht drauf komme. Kann sich jemand dazu herablassen, mal nen klitzekleinen Hinweis zu geben?

Grüße aus Berlin

Christoph S.

  1. Hallo,

    ich mach das mit grep so...

    @htmldateien = ();
    opendir(DIR,"$pfad");
    for $dateien (grep {/(.htm|.html)/} readdir DIR) {
    push(@htmldateien, $dateien);
    }
    closedir(DIR);

    Da ist . und .. schon weg und man kann das leicht auf die Dateitypen anpassen.

    Gruß
    Helmut

    1. Moin, Helmut

      das trifft aber eine Datei namens zB. qqqhtml.php

      kleine Verbesserung, falls tatsächlich nur die Endungen
      htm oder html erwischt werden sollen:

      opendir(VERZ, "$basedir" ) || die $!;
      push @htmldateien, $_  for grep{/.html?$/} readdir VERZ;
      closedir(VERZ);

      gruß

      werndt

    2. moin Helmut,

      ich mach das mit grep so...

      Jow, ich auch ;-)

      @htmldateien = ();
      opendir(DIR,"$pfad");
      for $dateien (grep {/(.htm|.html)/} readdir DIR) {

      ich darf das mal verbessern:
      my @files = grep {/^.*(.htm$|^.*.html$)/i} readdir DIR;

      => also den punkt maskieren und die Anker nicht vergessen, das macht die regex sicherer (/i => insensitive case, falls gewünscht).

      at Christoph: Schau Dir mal File::Find und File::Basename an das ist auch ganz interessant.

      Viele Grüße, Rolf

      1. hallo,

        ich mach das mit grep so...
        Jow, ich auch ;-)

        Ich hatte grep schonmal drin, das ist aus irgendwelchen Gründen, vielleicht sogar aus Versehen, wieder rausgeflogen.

        my @files = grep {/^.*(.htm$|^.*.html$)/i} readdir DIR;

        Sieht recht zuverlässig aus, ja.

        => (/i => insensitive case, falls gewünscht).

        Im Moment noch nicht, das kann warten.

        at Christoph: Schau Dir mal File::Find und File::Basename an das ist auch ganz interessant.

        Ok, werde ich machen, danke.

        Grüße aus Berlin

        Christoph S.

  2. Hi,

    $cgi->start_html(-title =>'Verzeichnis auslesen', -style =>{'src'=>$css}).

    Versuche doch mal alternativ, das HTML einfach mit

    print '<html><title>....';

    auszugeben. Ist nicht sonderlich schwierig, wenn man HTMl kann (wovon ich bei dir ausgehe ;-) und IMHO erheblich übersichtlicher, als die zahllosen verschachtelten CGI-Funktionen

    if ($zeile ne '.' && $zeile ne '..') {

    and hat die gleiche Funktionalität wie && und ist einfacher lesbar.

    (die das Durchsuchen des übergeordneten Verzeichnisses unterbindet) noch irgendwie durch irgendein "elsif" ergänzen, mit dem auch die Dateien, die _nicht_ *.htm sind, von der Erfassung

    ausgeschlossen werden.

    if ($zeile=~m/.htm?$/)
    überprüft, ob der Dateiname auf .htm oder .html endet.

    HTH

    wunderwarzenschwein

    --
    ss:} zu:$ ls:} fo:| de:] va:) ch:? sh:( n4:# rl:? br:> js:| ie:( fl:{ mo:)
    1. hi,

      Versuche doch mal alternativ, das HTML einfach mit
      print '<html><title>....';
      auszugeben. Ist nicht sonderlich schwierig, wenn man HTMl kann (wovon ich bei dir ausgehe ;-)

      Die HTML-Ausgabe ist tatsächlich überhaupt kein Problem. Allerdings verwende ich ganz bewußt den "CGI-Kram", weil ich das Modul nun endlich gerne richtig handhaben können möchte.

      IMHO erheblich übersichtlicher, als die zahllosen verschachtelten CGI-Funktionen

      Naja, wenn man sich eingefuchst hat, ist das mit dem CGI-Modul sogar überichtlicher und etwas knapper.

      if ($zeile=~m/.htm?$/)
      überprüft, ob der Dateiname auf .htm oder .html endet.

      So weit bin ich noch nicht (das betrifft die zweite foreach-Schleife, wo ich oben vorläufig [tu irgendwas] geschrieben habe), und _dort_ komme ich mit den RegExpressions klar.

      Ich werde es erstmal wieder mit grep probieren, daran hatte ich jetzt ein paar Tage nicht gedacht.

      Grüße aus Berlin

      Christoph S.

    2. auszugeben. Ist nicht sonderlich schwierig, wenn man HTMl kann (wovon ich bei dir ausgehe ;-) und IMHO erheblich übersichtlicher, als die zahllosen verschachtelten CGI-Funktionen

      Wieso verschachtelt?
      Wenn du CGI mit all seinen Möglichkeiten einsetzt, hast du einen sehr übersichtlichen Code in dem du kaum noch HTML brauchst und gerade für Formulare und Tabellen sind die Funktion optimal ausgelegt. Du kannst mit Listen in allen formen arbeiten.

      Versuch mal ein select feld so hin zu kriegen:

      use CGI;
      my %values =
      (
       wert1 => "bla 1",
       wert2 => "bla 2",
       wert3 => "bla 3",
       wert4 => "bla 4",
       wert5 => "bla 5",

      );

      print CGI::popup_menu(
      -NAME    => 'test',
      -default => 'wert4',
      -values  => [sort keys %values],
      -labels => %values
      );

      Es wird auf jeden Fall nicht so übersichtlich sein.

      Struppi.