Bakka: Zeilen aller Dateien eines Verzeichnisses zaehlen

Hailo...
Problem: ich moechte gerne alle Zeilen von Dateien eines bestimmten types in einem Verzeichnis Zaehlen...

Mein unten stehendes skript sollte(so meine ich) diese aufgabe erledigen
es liest allerdings nur die erste Datei...
wenn man allerding statt des ARGV z.B. ein *.pl einsetzt dann funktioniert es richtig...
ich will es aber "flexibel" halten.
--> Frage also: warum macht es das so wie es es tut?
und wie kann ich mein skript davon ueberzeugen so zu arbeiten wie ich es will?

Vielen Dank im Vorraus,

Bakka

hier mein skript:

#!/usr/local/bin/perl
#------------------------------------------------------------
#   Program to count rows

by: bakka created:27.04.2000

#------------------------------------------------------------
$anzahl=0;
foreach $filename (<$ARGV[0]>)
{
  @file="";
  pop(@file);
  open(LESEN,"<$filename")die"$!";
  @file=(<LESEN>);
  close(LESEN);
  for (@file)
  {
    $anzahl++;
  }
  print $filename
}
print "Zeilen gesamt: $anzahl \n";

  1. Hallo, (ungeprüft)

    $typ = ".txt";

    opendir(DIR,$dir); # dir auslesen auf Array @x_files    
    @x_files = grep ((!/^./ and /$typ/),readdir(DIR));
    closedir (DIR);

    Und dann das Array abarbeiten...; Rolf

    1. Hallo, Korrektur (sorry für den Müll von vorhin)

      $dir = "c:/temp";
      $typ = "nt";

      opendir(DIR,$dir);
      @x_files = grep ((!/^./ and /.$typ$/),readdir(DIR));
      closedir (DIR);

      foreach $file (@x_files){...}# Rolf

  2. hallo Bakka,

    Naja..wenn es die Zeilen der Dateien zählen soll, die du als Argument übergibst, dann geht es so:

    foreach $filename (@ARGV) {
    open (FILE, "<$filename) or die "Could not open $filename";
    @lines=<FILE>;
    close(FILE);

    $anzahl=$anzahl + $#lines; # ($#lines ist die länge desArrays @lines)
    }

    print "Es wurden $anzahl Zeilen gezählt";

    Wenn du allerdings alle Dateien eines bestimmten Typs öffnen möchtest, dann musst du schon eine Directory Listing einlesen und die die richtigen Dateien daraus filtern. Den Syntax dazu programmierst du bitte selber zusammen.

    Gruß
    Marcell

  3. Hallo Bakka!

    Mein Vorschlag (getestet):

    use File::Find;
    @ARGV[0] = qw(.) unless @ARGV[0];
    #File-Liste erstellen (incl. Verzeichnissen)
    $ext=@ARGV[1];
    find sub { push (@flist, $File::Find::name) }, @ARGV[0];
    #alle Files/Verzeichnisse aus Liste bearbeiten
    print "Bearbeitete Verzeichnisse:\n";
    $files=0;
    $dirs=0;
    $anzahl=0;
    foreach (@flist){
       if (($_ =~ /$ext/) and (-f $_)){
          $files ++;
          open(LESEN,"<$_")die"$!";
          @file=<LESEN>;
          close(LESEN);
          foreach (@file){
            $anzahl ++;
          }
       }elsif (-d $_) {
       #das hier ist nur ein Verzeichnis
          $dirs ++;
          print "$_\n";
       }
    }
    print "$anzahl Zeilen in $files Datei(en) und $dirs Verzeichniss(en)!\n";

    Aufruf: perl.exe script.pl dir ext
    "dir" ist das Verzeichnis in dem gesucht wird (incl. der darunter liegenden)
    "ext" ist die ein Teil des Dateinamens. z.B. die extention

    Gruß Frank

  4. hi!

    Problem: ich moechte gerne alle Zeilen von Dateien eines bestimmten types in einem Verzeichnis Zaehlen...

    Ich hab mal ein kleines Perl-Programm zum ziemlich genauen zählen der effektiven Sourcezeilen geschrieben,
    vielleicht kannst du damit was anfangen (funktioniert zu Zeit für Perl und C++ Kommentare).

    === cut ===
    #!/usr/bin/perl

    cl.pl v1.27 - (c) Copyright by Frank Schoenmann fs@tower.de, 2000.

    Count lines in a range of files

    if (!@ARGV)
    {
        print <<EOT;

    Usage: cl.pl [-C] [-B] <files>

    -C   do not count lines which are (perl or c++) comments
      -B   do not count blank lines
    EOT
        exit;
    }

    for (@ARGV)
    {
        if (/-C/) { $nocomments++; }
        if (/-B/) { $noblanklines++; }
        if (/-CB/ /-BC/) { $nocomments++; $noblanklines++; }
    }

    if (!<$ARGV[$#ARGV]>)
    {
        print "Error: File(s) '$ARGV[$#ARGV]' not found.";
        exit;
    }

    for (<pop $ARGV[$#ARGV]>)
    {
        if (-T $_)
        {
            open FILE, $_;
            while (<FILE>)
            {
                $lines++;

    if ($nocomments)
                {
                    if (/^\s*#/) { $lines--; $comments++; }
                    if (/^\s*///) { $lines--; $comments++; }
                    $update++;
                }
                if ($noblanklines)
                {
                    if (/^\s*$/) { $lines-- if $update; $blanklines++; }
                }
                $update--;
            }
            close FILE;
        }
    }

    print "$lines Zeilen";

    $nocomments && $noblanklines && print " ohne Kommentare und Leerzeilen (", $comments + $blanklines, " Zeilen)";
    $noblanklines $nocomments && print " ohne Kommentare ($comments Kommentarzeilen)";
    $nocomments $noblanklines && print " ohne Leerzeilen ($blanklines Leerzeilen)";
    === cut ===

    Funktioniert bei mir ziemlich gut, und dürfte auch so ziemlich alle reinen Kommentarzeilen und Leerzeilen
    rausfiltern.

    bye, Frank!

  5. Vielen Dank fuer die hilfe.. ich bin jetzt einen schritt weiter und
    klueger:
    Das problem ist, dass wenn man *.pl als parameter eingibt, sich das
    skript die erste datei mit der Endung pl schnappt und fuer ARGV[0]
    einsetzt...somit muss ich tatsaechlich zuerst ein directorylisting
    erstellen um dann die dateien aus diesem listing zu holen...
    Eine andere moeglichkeit besteht darin, schon beim aufruf des skripts
    die parameter zu escapen... z.B. countrows.pl /pfad/\*.pl

    Vielen Dank auf jeden Fall

    gruss Bakka