2017-03-27 4 views
-1

Ich erstelle ein Skript, das ich in einem bestimmten Ordner öffne, der zwei verschiedene Dateitypen enthält. 'Sichere' (secure.text, secure.001.text usw.) Dateien und 'message' (message.txt, etc) Dateien. Jede Datei enthält ein Protokoll für Jahr, Tag, Datum, Stunde und Minute. Ich möchte in der Lage sein, diese Dateien zu scannen und eine neue Datei zu erstellen, die alle Protokolleinträge für Januar 2006 enthält. Der Zweck dieses Skripts ist es, nur einen Satz von Daten (sicher) und nicht alles (nur) zu scannen (Mitteilungen).Skript, um den Ordner zu scannen, in dem sich das Skript befindet, und nach bestimmten Dateien zu suchen [Perl]

Ich habe Probleme mit meinem Skript finden das aktuelle Arbeitsverzeichnis. Zu meinem Verständnis verwendet Perl den Ort des Skripts als aktuelles Verzeichnis. Ich benutze die opendir und closedir Funktionen, und werde aufgefordert, dass es 60 Dateien innerhalb des Verzeichnisses des Skripts gibt, aber wenn ich einige Dateien lösche, nur um es zu testen, sagt es immer noch 60, was mich zu der Annahme verleitet, dass dies nicht die Aktuelles Verzeichnis. Es findet auch nicht "sicher", trotz der richtigen Regex.

Die Ausgabe, die ich erhalte, ist "Problem, Datei 'sicher' zu finden."

#!/usr/bin/perl 


use strict; 
use warnings; 



#Locate and scan all of the files 

#list all files in same dir as this perl script. 
my $dirname = "."; 
opendir(my $dh, $dirname) #sets $dh as the current working directory 
    or die "Can't open dir '$dirname':$!\n"; #Kills if can not open current directory. 
my @all_the_file; #Instantiates new variable that accounts for all of the files in the current dir. 
while(my $file = readdir($dh)) { #$file accounts for every file on device. 
    push(@all_the_file, $file); #Pushes files in current directory to $file. 

} 
closedir($dh); 

#Gets all of the secure files. 

my @all_the_secure_file; 
@all_the_secure_file = grep(/^secure(\.\d{1,2})?$/, @all_the_file); 

#Itterate over secure files. 

my $filename = "secure"; 
open(my $fhin, "<", $filename) 
    or die "Can't open '$filename':$!\n"; 
chomp(my @lines = <$fhin>) ; 
close($fhin); 

#Match the Regex of Jan. 

my @jan_lines = grep(/^Jan/ , @lines) ; 
print "The file '$filename' = " . @lines . " lines.\n"; 
print "Size of \@jan_lines = " . @jan_lines . "\n"; 

#Print and create new file with Data. 

my $filename2 = "secure.1"; 
open(my $fhin, "<", $filename) 
    or die "Can't open '$filename':$!\n"; 
chomp(my @lines2 = <$fhin>) ; 
close($fhin); 

my @jan_lines2 = grep(/^Jan/ , @lines2) ; 
print "The file '$filename2' = " . @lines2 . " lines.\n"; 
print "Size of \@jan_lines2 = " . @jan_lines2 . "\n"; 

exit; 
+0

Die Lage des Skripts ist nicht unbedingt das aktuelle Arbeitsverzeichnis. Das aktuelle Arbeitsverzeichnis ist das aktuelle Arbeitsverzeichnis. Schauen Sie sich zum Beispiel die Module [Cwd] (http://perldoc.perl.org/Cwd.html) und [FindBin] (http://perldoc.perl.org/FindBin.html) an. –

+0

Auch "über sichere Dateien iterieren" und "neue Datei mit Daten drucken und erstellen" tun eigentlich nicht, was die Kommentare sagen, sie tun ... –

+0

Basic Debugging: (1) Set $ ​​Dirname auf den tatsächlichen Pfad (hard-code es) (2) Was du von "opendir" bekommst, hat den Pfad nicht! Setzen Sie also '$ dirname' auf was 'opendir' zurückgibt. // Dann scannen Sie Dateien in diesem '$ dirname'. // Bitte lies keine Dateien _ zum Testen! Warum drucken Sie sie nicht einfach auf den Bildschirm und prüfen, ob sie korrekt sind? Denken Sie daran, sie müssen den vollständigen Pfad haben. Sie können auch mit 'if (nicht -f $ datei) {print" No $ file \ n "}' testen und sehen, ob diese _strings_ (Name '$ file') tatsächliche Dateien auf dem System sind. // Es gibt andere Probleme, aber das ist ein Anfang. – zdim

Antwort

1

Sie sollten wirklich ein Modul verwenden. Im folgenden Beispiel wird Path::Tiny verwendet.

use 5.014; 
use warnings; 
use Path::Tiny; 

my $root = path("/some/path"); 
my $iter = $root->iterator({recurse => 1}); 

while(my $path = $iter->()) { 
    next unless $path->basename =~ /(secure|message)\.(\d+)?\.txt/i; 

    my $type = $1; 
    #my $num = $2; #??? 

    my @lines = grep { /^Jan/ } $path->lines(); 
    say "in the $path is ", scalar @lines, " lines for Jan"; 

    my $new = path(($type =~ /secure/i) ? "/some/where/secure.txt" : "/some/nosecure/message.txt"); 
    $new->spew(@lines); 
} 

Nicht getestet, aber es sollte + tun - das gleiche wie Ihr Skript, noch mehr, weil es recurseively Aufsuchen ...

+0

ist Pfad ("/ irgendein/Pfad"); Festlegen des Standardpfads für den Speicherort der Datei? –

+1

@MatthewParise Wenn mit "_default path_" meinst du den vollständigen Pfad, ja ist es. Wenn es wichtig ist, dass Sie den Pfad relativ zum Skript verwenden, können Sie feststellen, dass Sie 'FindBin' (und' Cwd') verwenden und dann den vollständigen Pfad erstellen, und dann können Sie dieses großartige Modul weiterhin verwenden. Diese Antwort gibt Ihnen so gut wie alles, was Sie brauchen können, und einen Blueprint für zukünftige Anwendungen. – zdim

+0

@MatthewParise Um ... sorry, 'path ($ dir)' erstellt ein Objekt für Datei/Verzeichnis unter '/ some/path'. Es wird hier $ root zugewiesen und danach können Sie die Methoden des Moduls auf $ root aufrufen. Der 'Pfad()' nimmt den vollständigen Pfad zu Datei/Verzeichnis, was '/ einige/Pfad' ist (das ist, was ich in dem obigen Kommentar meinte). – zdim

Verwandte Themen