Moin,
voran: ich bin ein absoluter Perl Noob und bin darum wahrscheinlich auch zu doof, google zu bedienen (nein bei ChatGPT war ich noch nicht). Ich suche in einer Directory Structur eine Liste von Files, die aktueller sind als ein Referenz-File. Aktuell mache ich das so:
my @files1 = `find /path/to/pen8*/pools/*/logf -type f -newer $touchfile -name "Psipenta_*.log" 2> /dev/null`;
In $touchfile findet sich der Name meines Referenz-Files. Ich bin mir sicher, das kann man auch nativ in Perl machen. Bitte um Hilfe.
Danke, Hilmar -- sigfault
Hallo,
On Sat, Feb 11, 2023 at 12:50:20PM +0100, Hilmar Preuße wrote:
Moin,
voran: ich bin ein absoluter Perl Noob und bin darum wahrscheinlich auch zu doof, google zu bedienen (nein bei ChatGPT war ich noch nicht). Ich suche in einer Directory Structur eine Liste von Files, die aktueller sind als ein Referenz-File. Aktuell mache ich das so:
my @files1 = `find /path/to/pen8*/pools/*/logf -type f -newer $touchfile -name "Psipenta_*.log" 2> /dev/null`;
In $touchfile findet sich der Name meines Referenz-Files. Ich bin mir sicher, das kann man auch nativ in Perl machen. Bitte um Hilfe.
---- snip ---- #!/bin/perl # use warnings; use strict;
use File::stat; use File::Find; use Data::Dumper;
my $touchfile = 'ref.txt';
my $touchstat = stat($touchfile) or die "No $touchfile: $!";
my @files = (); my $wanted = sub { my $stat = stat($_); push @files, $File::Find::name if -f $stat && $stat->mtime > $touchstat->mtime; # TODO check name };
find($wanted, glob("/path/to/pen8*/pools/*/logf"));
print Dumper(@files); ---- snip ----
Den Match für den Filenamen bekommste selber hin :-)
https://perldoc.perl.org/File::Find https://perldoc.perl.org/perlrequick
viel Spass.
Grüsse Andreas
Am 11.02.2023 um 16:36 teilte Andreas Fett mit:
Moin,
Den Match für den Filenamen bekommste selber hin :-)
Habe mich schwer getan, aber ich denke ich habs. Bin halt kein Programmierer. Hier nur der Teil, den ich geändert habe.
my $touchfile = '/var/log/icinga/Log_stamp'; my $touchstat = stat($touchfile) or die "No $touchfile: $!"; my $filePattern = 'Name_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_.*.log$' ; my @files = ();
my $wanted = sub { my $stat = stat($_); return unless -f $stat; return unless $stat->mtime > $touchstat->mtime; return unless /$filePattern/; push @files, $File::Find::name; };
find($wanted, glob("/var/log/icinga/logs"));
Danke, Hilmar -- sigfault
Hallo,
On Sun, Feb 12, 2023 at 03:48:36PM +0100, Hilmar Preuße wrote:
Am 11.02.2023 um 16:36 teilte Andreas Fett mit:
Moin,
Den Match für den Filenamen bekommste selber hin :-)
Habe mich schwer getan, aber ich denke ich habs. Bin halt kein Programmierer. Hier nur der Teil, den ich geändert habe. ...
find($wanted, glob("/var/log/icinga/logs"));
Dass glob() ist die Filenameexpansion wie in der Shell. Ich hatte das drin, weil Dein ursprüngliches Beispiel dort "/path/to/pen8*/pools/*/logf" verwendet hatte. Wenn der Pfad ohne wildcards ist wie oben brauchst Du das glob() nicht.
Grüsse Andreas
Am 12.02.2023 um 16:13 teilte Andreas Fett mit:
On Sun, Feb 12, 2023 at 03:48:36PM +0100, Hilmar Preuße wrote:
Moin,
find($wanted, glob("/var/log/icinga/logs"));
Dass glob() ist die Filenameexpansion wie in der Shell. Ich hatte das drin, weil Dein ursprüngliches Beispiel dort "/path/to/pen8*/pools/*/logf" verwendet hatte. Wenn der Pfad ohne wildcards ist wie oben brauchst Du das glob() nicht.
Ja, danke. Das brauche ich auch. Die Pfadangabe ohne Wildcards sind erstmal vom Test-System, da sind die File-System Strukturen etwas anders.
Hilmar -- sigfault
Hallo,
On Sun, Feb 12, 2023 at 03:48:36PM +0100, Hilmar Preuße wrote:
my $wanted = sub { my $stat = stat($_); return unless -f $stat; return unless $stat->mtime > $touchstat->mtime; return unless /$filePattern/; push @files, $File::Find::name; };
find($wanted, glob("/var/log/icinga/logs"));
Eine Anmerkung noch. Es ist eventuell effizienter, wenn Du den Check auf den Filename vor das stat() legst. Ich bin mir nicht 100% sicher, ob das im konkreten Anwendungsfall wirklich nen Unterschied macht, aber solche syscalls grad bei Filesystemzeugs sind in Perl tendenziell teuer. (in C würd ich das definitiv davor legen)
Grüsse Andreas
On 2/13/23 01:11, Andreas Fett wrote:
On Sun, Feb 12, 2023 at 03:48:36PM +0100, Hilmar Preuße wrote:
Hallo,
my $wanted = sub { my $stat = stat($_); return unless -f $stat; return unless $stat->mtime > $touchstat->mtime; return unless /$filePattern/; push @files, $File::Find::name; };
find($wanted, glob("/var/log/icinga/logs"));
Eine Anmerkung noch. Es ist eventuell effizienter, wenn Du den Check auf den Filename vor das stat() legst. Ich bin mir nicht 100% sicher, ob das im konkreten Anwendungsfall wirklich nen Unterschied macht, aber solche syscalls grad bei Filesystemzeugs sind in Perl tendenziell teuer. (in C würd ich das definitiv davor legen)
OK, danke für Deinen Input; habe es jetzt so geändert. An der Laufzeit des Skriptes ändert sich dadurch aber wenig, denn die echten Zeitfresser sind weiter hinten.
Hilmar -- Testmail
Hilmar Preuße hille42@web.de (Sa 11 Feb 2023 12:50:20 CET):
Moin, zu doof, google zu bedienen (nein bei ChatGPT war ich noch nicht). Ich suche in einer Directory Structur eine Liste von Files, die aktueller sind als ein Referenz-File. Aktuell mache ich das so:
my @files1 = `find /path/to/pen8*/pools/*/logf -type f -newer $touchfile -name "Psipenta_*.log" 2> /dev/null`;
Das wäre meine Variante:
``` #!/usr/bin/perl use strict; use warnings; use File::Find; use File::FnMatch 'fnmatch';
my $touchfile = shift // die "need name of touchfile\n"; my @dirs = @ARGV or die "need directories\n";
sub newer { my $files = shift; my $ref = -M shift; my $pattern = shift; return sub { return unless fnmatch $pattern, $_; # name is cheap return unless -f; # implies a stat, may be expensive return if -M _ > $ref; # "_" uses stat cache push @$files, $File::Find::name; } }
my @files; find(newer(@files, $touchfile, "*.log"), @dirs); print join "\n", @files; ```
lug-dd@mailman.schlittermann.de