我是perl的新手,我曾经使用过C#
我每天要多次解析一些防病毒数据的多个xml文件。 我正在尝试将其命名为该月的当前日期(即20190425)。虽然名称相同,但会追加到该文件,如果是新日期(即20190426),它将创建该新文件并开始追加到该文件。
我在考虑使用日志功能,因为它可以检查文件名是否存在,所以我可以“自动”进行检查。
打开(LOG,“ >> report.txt”); #追加到report.txt
我可以用当前日期在此名称上盖章吗?所以会是 例如,20190425-Report.txt?这样,它将自动创建一个新文件“明天”并开始向其中添加
要使脚本的名称与当前日期相同。
答案 0 :(得分:2)
Time::Piece模块更改了标准的localtime()
函数,以便它返回代表当前时间的对象。该对象有一个strftime()
方法,该方法将以使用传递给该方法的模板格式化的字符串的形式返回该时间。
use feature 'say';
use Time::Piece;
my $now = localtime;
say $now->strftime('%Y%m%d'); # %Y = year; %m = month; %d = date
您可以在代码中像这样使用它:
use feature 'say';
use Time::Piece;
my $now = localtime;
my $today = $now->strftime('%Y%m%d');
# Note: I've switched to the three-arg version of open()
# and a lexical filehandle. Both are considered best practice.
# I've also checked the return value from open() and killed
# the program if it fails.
open my $log_fh, '>>', "$today-Report.txt"
or die "Cannot open $today-Report.txt: $!";
更新:在后续回答中,您谈到尝试我的代码时出错。您可能会怀疑,这些错误均源于您所使用的Perl的较旧版本。 Perl 5.6.0于2000年3月发布,我应该指出,很长一段时间以来,Perl开发团队一直完全不支持它。 Perl 5.10.0(于2007年12月发布)中全部添加了给您带来问题的功能。我认为版本5.10是用于合理的现代Perl开发环境的绝对最低版本。我强烈建议您升级到Perl的最新版本。
话虽如此,在您的Perl古代版本中(当然)可以做到这一点。
use POSIX 'strftime';
my $today = strftime('%Y%m%d', localtime);
print "Today is: $today\n";
my $filename = "$today-Report.txt";
# I'm not sure when modern file-opening practices
# were added to Perl, so I've reverted to using a
# really old syntax.
open LOG, ">>$filename"
or die "Cannot open $filename: $!";
答案 1 :(得分:0)
非常感谢您提供答案,但是我仍然无法编译脚本。
在我使用您编写Dave的示例时,出现错误。我想这可能与版本有关吗?据我所知,该脚本位于Perl 5.6中
在@INC中找不到feature.pm(@INC包含:C:/perl/perl-5.6.0-win/lib C:/perl/perl-5.6.0-win/site/lib。)
同样需要 “使用时间::件;
在@INC中找不到Time / Piece.pm
而且我似乎也无法使$ filename = strftime起作用。
如果我遵循阿比盖尔的例子,我会得到
在dirlist.pl第63行没有包或对象引用的情况下,无法调用方法“ say”。
对我来说,这似乎是最接近工作的示例。
然后我尝试使用“打开”并得到
“严格”时不能使用字符串(“ 20190426-report.txt”)作为符号引用 refs”在dirlist.pl第62行使用。
对于其中任何一个是Perl的基本功能,我深表歉意,并试图弄清楚。我知道未使用的变量并注释掉了函数(这就是我试图将它们拼凑起来),但是我的首要任务是使脚本按预期工作,然后进行一些清理。
这是脚本
#!/usr/bin/perl
use strict;
use warnings;
use POSIX;
use File::stat;
use File::Basename;
use File::Find;
use File::Copy;
use POSIX qw(strftime);
#To look for more in the virus, add name to array and increase the switch elsif
my @NAMES = ("Name", "VirusDefinitions", "IPAddress", "OperatingSystem", "AgentVersion", "Infected", "LastScanTime","LastUpdateTime" );
my $DEBUG = 2; # debug on = 1 low, = 2 detailed, = 3 full, = 0 OFF. Will print to screen needed in file the pipe >filename
my $DETAILED = 0; #
#vars
my $path = $ARGV[0];
my $TXT = $ARGV[1];
my $DIR2 = "XX"; #This returns the main dir
my $DIR3 = "XX";
my $PROJNO = "XX";
my $FILE1 = "XX"; #This returns the filename
my $CUST = "XX";
my $FILEA="$DIR3\\$FILE1"; #This returns the complete filepath "x:\\folder\\file.txt"
my $NAME="XX";
my $VIRUSDEF="XX"
;my $IP="XX";
my $OS="XX";
my $AGNT="XX";
my $INFEC="XX";
my $LAST="XX";
my $DATE = strftime "%d/%m/%Y", localtime; #Store local (server) time in the $DATE variable
my $LASTUP ="XX";
my $entr = "XX";
my $logname = "report.txt";
my ($day, $month, $year) = (localtime) [3, 4, 5];
my $file_name = sprintf "%04d%02d%02d-report.txt" =>
$year + 1900, $month +1, $day;
#make current date time below and 2 digit
my ($sec,$min,$hour,$mday,$mon,$wday,$yday,$isdst) = localtime();
$mon +=1;
my $DATO = sprintf("%02d%02d%02d", $year, $mon, $mday);
# reinitialiser report vars to make sure we can see if we miss one
sub init {
my $NAME="XX";
my $VIRUSDEF="XX";
my $IP="XX";
my $OS="XX";
my $AGNT="XX";
my $INFEC="XX";
my $LAST="XX";
my $LASTUP="XX";
}
#save fixed details
#open (LOG, '> Report.txt'); #Overrite report.txt
#open (LOG, '>> Report.txt'); #Append to report.txt
#print LOG "Project, Customer-Site, LastUpdateTime, Server-Name, Definition-File, IP-address , Operating-Sys, Agent-Version, Infected, Last-Scan-Time, AntiVirus-file\n" ; #Commented out as we're already defining the values.
#open my $log_fh, '>>', "$today-report.txt"
# or die "Cannot open $today-report.txt: $!";
open $file_name;
sub report {
$FILEA="$DIR3\\$FILE1";
if ($DEBUG){print "report: $PROJNO\n";}
if ($DEBUG){print "report: $CUST\n";}
if ($DEBUG){print "report: $FILE1\n";}
if ($DEBUG){print "report: $FILEA\n";}
if ($DEBUG){print "report: $LASTUP\n";}
open( FIL, "< $FILEA" )|| die "cant open file $!" ; #This is the filehandler
while (defined ($_ = <FIL>)) {
foreach my $N (@NAMES) {
#print "looking for $N\n" ;
if ($_ =~ /$N/) {
if ($DEBUG gt 2){print "report: Looking for $N\n";}
$_ =~ /$N(.*)$N/;
my $TMP = $1;
$TMP =~ s/[\$#@~!&*()<>\[\];,?^ `\\\/]+//g;
#Switch that has to be extended if the array NAMES is extended
if ($N eq "Name") {
$NAME=$TMP;
}elsif ($N eq "VirusDefinitions"){
$VIRUSDEF=$TMP;
}elsif ($N eq "IPAddress") {
$IP=$TMP;
}elsif ($N eq "OperatingSystem") {
$OS=$TMP;
}elsif ($N eq "AgentVersion") {
$AGNT=$TMP;
}elsif ($N eq "Infected") {
$INFEC=$TMP;
}elsif ($N eq "LastScanTime") {
$LAST=$TMP;}
elsif ($N eq "LastUpdateTime") {
$LASTUP=$TMP;
}
#}elsif ($N eq "Date") {
#$DATE=strftime;
print LOG "date: $DATE, Last Update Time: $LASTUP, pnr: $PROJNO, site: $CUST, serv: $NAME, def: $VIRUSDEF, ipadr: $IP, os: $OS, agntver: $AGNT, inf: $INFEC, lscan: $LAST, file: $FILE1\n" ;
#init variables again
init
}
else{
#print "no match $N\n"
}
}
#close myfile ;
}
if ($DEBUG){print "report: copy $PROJNO.$FILE1 to Avold\n";}
copy ( "$FILEA", "c:\\Avold\\$PROJNO.$FILE1") ;
if ($DEBUG){print "options to script : $path AND $TXT : DATE was : $DATO \n ";}
#if argv txt make a copy of the xml as txt file customer_attachments.
if ( $TXT eq "txt" ){
#chop($CUST);
if ($DEBUG){print "inside if options to script : $path AND $TXT DATO =$DATO \n";}
copy ( "$FILEA", "c:\\AVDownload\\_Customer_attachments\\$PROJNO-$DATO-AntiVirusReport-$CUST.txt") ;
}
#Close filehandler/file so that we can unlink/delete the file
close FIL ;
#remove the files if a copy exists
if ( -e "c:\\Avold\\$PROJNO.$FILE1")
{
unlink glob "c:\\AVDownload\\$entr\\*.xml";
print "$path $entr\n";
print "file : $PROJNO.$FILE1: DIR2=$DIR2 and DIR3=$DIR3\n";
}else{
print "file is not there";
}
} #end report
# unless -d $path;
#main
opendir( my $DIR, $path );
while ( my $entry = readdir $DIR ) {
next unless -d $path . '/' . $entry;
next if $entry eq '.' or $entry eq '..';
$DIR2 = $path . $entry . '\\' ;
$DIR3 = $path . $entry ; #\$entry";
$entr=$entry ;
my @names = split /_/, $DIR2, 2 ;
$PROJNO = $names[0];
$PROJNO =~ s/\D//g ;
$CUST = $names[1];
chop($CUST);
if ($DEBUG gt 1){print "main: $PROJNO and $CUST\n";}
if ($DEBUG gt 1){print "main: $DIR2\n";}
opendir my $dh, $DIR2 or die "Error opening $DIR2: $!";
#my @files = grep(/AntiVirus.zip$/,readdir($dh));
my @files = grep(/AntiVirus.xml$/,readdir($dh));
if (!@files) {
#print "$files[$#files]\n";
if ($DEBUG gt 1){print "main: array was empty = no .zip files found\n";}
if ($DEBUG gt 1){print "main: No antivirus zip files found\n";}
print LOG "$PROJNO, $CUST\n" ;
#report
}else{
if ($DEBUG gt 1){print "main: One or more Antivirus files found, we'll take the newest\n";}
#print "$files[$#files]\n";
$FILE1=$files[$#files];
#call report
report
}
closedir $dh;
}
closedir $DIR;
close LOG ;