Code runs sometimes, sometimes gives error on linux host.
Need to check why has is not printing,
Error, messages: Use of uninitialized value in sprintf at ./fa_list.pl line 139, line
Can someone check, why I'm getting error?
use Getopt::Long;
my $sid = '9999';
my $Fa_VSan_Map = 'Fa_VSan_Map';
sub usage {
my $message = $_[0];
if (defined $message && length $message) {
$message .= "\n"
unless $message =~ /\n$/;
}
my $command = $0;
$command =~ s#^.*/##;
print STDERR (
$message,
"usage: $command -sid xxx -outf FA_Mapping\n" .
"Where -sid: is primary SID to show mappings.\n" .
" -outf: Output File prefix.\n" .
" -Reserved...\n"
);
die("\n")
}
GetOptions( 'sid=i' => \$sid, 'outf=s' => \$Fa_VSan_Map) or
usage("Invalid commmand line options.");
print($sid);
my $outf = "$Fa_VSan_Map$sid.csv";
my $outf1 = "Fa_VSan_Map1$sid.csv";
my ($mydir,$dir_port,$dir_port_wwpn,$FaWWPN);
my (%FA,%FAH,%FAC,%VSAN);
my ($wwpn,$host,$port,$fcid,$logged,$fab);
# 50:00:09:72:08:4b:05:89, => cdc02-core1-1.yyyyy.xxxx.com,CISCO,fc3/12,VS251,50:00:09:72:08:4b:05:89,,8,Active
# cdc02-core-1-2.yyyyy.xxxx.com,CISCO,fc1/29,VS251,50:00:09:73:00:1c:e1:1c,,8,Active
sub LoadVSAN()
{
my $vsanf = "VSAN$sid.csv";
print ($vsanf);
open (VSAN, "<", $vsanf) or die "Could not open $!";
while (<VSAN>) {
if (/Active/) {
my #array = split /,/;
print (#array);
my $key = $array[4];
$key =~ s/://g;
my #line_arranged = ($array[3],$array[2],$array[0],$array[6],$array[7]);
$VSAN{$key} = \#line_arranged;
print($key, ": ", #{$VSAN{$key}}, "\n");
}
}
close VSAN;
}
LoadVSAN;
# foreach my $key (%VSAN) {
# print(${VSAN{$key}}[0]); print("\n");
# ${$VSAN{$FaWwpn}}[0]
# }
open (OUT, ">", $outf) or die "Could not open $outf $!";
open( OUT1, ">",$outf1) or die "Could not open $outf1 $!";
my $sidtxt = "sidcfg.fa$sid.txt";
my $cmd = 'symcfg -sid ' . $sid . ' list -fa all -v > ' . $sidtxt;
system($cmd);
open ( SYM, "<" , $sidtxt ) or die "Could not open $sidtxt $!";
while ( <SYM>) {
chomp ;
if (/Director Identification:/) {
$mydir = $_;
$mydir =~ s/\s+Director Identification: //;
$mydir =~ s/FA-//;
}
elsif (/Director Port:/) {
$port = $_;
$port =~ s/\s+Director Port: //;
$dir_port = sprintf '%04d_%03s_%03d', int($sid), $mydir, int($port);
}
elsif (/WWN Port Name/) {
$wwpn = $_;
$wwpn =~ s/\s+WWN Port Name\s+: //;
$dir_port_wwpn = sprintf '%s,%s', $dir_port, $wwpn;
$FA{$dir_port} = $wwpn;
}
}
close(SYM);
$sidtxt = 'symaccess.ll.' . $sid . '.txt';
$cmd = 'symaccess -sid ' . $sid . ' list logins > ' . $sidtxt;
#print($cmd);
system($cmd );
open ( SYM, "<" , $sidtxt ) or die "Could not open $sidtxt $!";
while ( <SYM>) {
chomp ;
if (/Director Identification/) {
$mydir = $_;
$mydir =~ s/Director Identification\s+:\s+//;
$mydir =~ s/FA-//;
}
elsif (/Director Port/) {
$port = $_;
$port =~ s/Director Port\s+:\s+//;
$dir_port = sprintf '%04d_%03s_%03d', int($sid),$mydir, int($port);
}
elsif (/Fibre/) {
($wwpn,undef, $host,$port,$fcid,$logged,$fab) = split;
my $host_port;
if( lc($host) eq 'null') {
$host_port = substr($wwpn,10,6);
}
else {
$host_port = $host . '_' . $port . '_' . substr($wwpn,12,4);
}
if (exists $FAH{$dir_port}) {
$FAH{$dir_port} .= ':' . $host_port;
$FAC{$dir_port} += 1;
} else {
$FAH{$dir_port} = $host_port;
$FAC{$dir_port} = 1;
}
if ( $logged eq "Yes") {
my $line = sprintf ( '%s,%s,%s,%s', $dir_port, $FA{$dir_port}, $host_port, $fcid);
print (OUT1 $line . "\n");
}
}
}
print OUT "Fa,FaWWPN,VSan,HostCount,PERCENT_BUSY,HostNames\n";
my $PERCENT_BUSY=10.0;
foreach my $fa ( keys %FAC) {
my $formula = '=VLOOKUP(B2,Sheet1!A$2:F$600,6,FALSE)';
my $FaWwpn = lc($FA{$fa});
#print($FaWwpn . ": " . $VSAN{$FaWwpn}->[0] . "\n" );
## Below is line 139
my $line = sprintf ('%s,%s,%s,%s,%3.2f,%s', $fa, $FaWwpn, ${$VSAN{$FaWwpn}}[0], $FAC{$fa}, $PERCENT_BUSY, lc($FAH{$fa}));
print OUT $line . "\n";
#print $line . "\n";
}
close(SYM);
I believe there is problem with lc($FAH{$fa}).
have you checked you initialized $FAH in your code ?
Related
I have a Perl script that is executed from Nagios XI.
It has two subroutines: SendEmail and SendTraps.
The script works fine when executed manually by passing the required parameters, but it doesn't work when triggered from Nagios. The script gets executed but the subroutines are skipped.
echo is working, but the two subroutines are not working even if the condition is met.
if ( ( $hoststatetype =~ m/HARD/ ) && ( $hoststate =~ m/DOWN/ ) ) {
`echo "HOST::$prihost $hostoutput">>/tmp/failover_log.txt`;
sendMail();
send_trap();
}
Full script here:
use strict;
use warnings;
use Text::CSV;
# Declared all the variables here
# Parsing input arguments
if ( $#ARGV > -1 ) {
if ( $ARGV[0] eq "-nagiosxi_trigger" ) {
$prihost = $ARGV[1];
$hoststate = $ARGV[2];
$hoststatetype = $ARGV[3];
$hostoutput = $ARGV[4];
}
elsif ( $ARGV[0] eq "-manual_trigger" ) {
$comment = $ARGV[1];
$userid = $ARGV[2];
$flag = "Failover-Trigger_Manual";
print "Maunal Failover triggered with comment: $comment by $userid\n";
$error_desc = "Maunal Failover triggered with comment: $comment by $userid";
send_trap();
sendMail();
exit 0;
}
else {
print STDERR "Invalid parameter $ARGV[0] \n";
exit 1;
}
}
else {
print STDERR "ERROR:No Arguments Passed.\n";
exit 1
}
# Check if Host or Service is in Hard/down state
if ( ( $hoststatetype =~ m/HARD/ ) && ( $hoststate =~ m/DOWN/ ) ) {
`echo "HOST::$prihost $hostoutput">>/tmp/failover_log.txt`;
sendMail();
send_trap();
}
elsif ( ( $hoststatetype =~ m/SOFT/ ) && ( $hoststate =~ m/DOWN/ ) ) {
`echo "HOST::$prihost $hostoutput">>/tmp/failover_log.txt`;
}
else {
`echo "HOST Good, $prihost $hostoutput">>/tmp/failover_log.txt`;
}
# Sub-Routines
sub failover {
my $csv = Text::CSV->new({ sep_char => ',' }) or die "Cannot use CSV: ".Text::CSV->error_diag ();;
my $file = "myxilist";
my $primary;
my $secondary;
#my $xienv;
my $host = `hostname`;
chomp $host;
open( my $data, '<', $file ) or die "Could not open '$file' $!\n";
while ( my $xi = <$data> ) {
chomp $xi;
if ( $csv->parse($xi) ) {
my #fields = $csv->fields();
if ( $fields[0] =~ m/$host/ ) {
$primary = $fields[1];
$secondary = $fields[0];
$xienv = $fields[2];
}
elsif ( $fields[1] =~ m/$host/ ) {
$primary = $fields[0];
$secondary = $fields[1];
$xienv = $fields[2];
}
}
else {
warn "Line could not be parsed: $xi\n";
exit 1;
}
}
my $failovermsg="failover successful from $primary to $secondary server";
return $failovermsg;
}
sub sendMail {
# Build the list for mailing out results
my $mailSubject;
my $mailID = "test\#mail.com";
my #results = failover();
$mailSubject = "Failover Successful on $xienv instance";
print "Sending email to $mailID \n";
`echo "sending Email">>/tmp/failover_log.txt`;
open MAILX, "|/usr/bin/mailx -s \"$mailSubject\" $mailID " or die $!;
print MAILX "#results";
close MAILX;
return;
}
sub send_trap {
# Sending SNMP traps
my #results = failover();
my $trap = `/usr/bin/snmptrap -v 2c -c public tcp:server:1010 '' MIB::Event Hostname s "$xienv" nSvcDesc s "$flag" nSvcStateID i 2 nSvcOutput s "#results"`;
return;
}
Any thoughts what could be missing?
Issue was in the failover() SubRoutine. I was calling a file "myxilist" that was present in the same directory as the script.
So, the script was working fine when called manually, but when it is triggered from application, script is getting executed from some other directory and the failover sub exits, as it's not able to open the file.
I've provided the full path of the file and the script works fine.
Thank you all for your help.
I want to program a perl script to change logs format. I want to remove --- from logs. Then separate the CRLF by |.
basically I want to obtain this result :
INFO|[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'|JB173F3N|17/02/15 14:32:03:930|Inbound Message | ID: 5 Response-Code: 200 | Encoding: UTF-8 | Content-Type: application/soap+xml; charset=utf-8 | Headers: {connection=[close], Content-Length=[650], content-type=[application/soap+xml; charset=utf-8], Date=[Tue, 17 Feb 2015 13:32:03 GMT], Server=[Apache], X-Powered-By=[Servlet/2.5 JSP/2.1]} | Payload: <?xml version="1.0" encoding="UTF-8"?> | <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header/><soap:Body><con:Reponse xmlns:con="http://www.erdfdistribution.fr/linky/types/smc/consultation"><con:IdPRM>19136758109411</con:IdPRM><con:CR><dico:Statut xmlns:dico="http://www.erdfdistribution.fr/linky/types/dico">Rejet</dico:Statut><dico:HorEmission xmlns:dico="http://www.erdfdistribution.fr/linky/types/dico">2015-02-17T14:32:03.887+01:00</dico:HorEmission><dico:Detail xmlns:dico="http://www.erdfdistribution.fr/linky/types/dico"><dico:Code>REJ016</dico:Code></dico:Detail></con:CR></con:Reponse></soap:Body></soap:Envelope>
Instead of this One:
INFO|[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'|JB173F3N|17/02/15 14:32:03:930|Inbound Message
----------------------------
ID: 5
Response-Code: 200
Encoding: UTF-8
Content-Type: application/soap+xml; charset=utf-8
Headers: {connection=[close], Content-Length=[650], content-type=[application/soap+xml; charset=utf-8], Date=[Tue, 17 Feb 2015 13:32:03 GMT], Server=[Apache], X-Powered-By=[Servlet/2.5 JSP/2.1]}
Payload: <?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header/><soap:Body><con:Reponse xmlns:con="http://www.erdfdistribution.fr/linky/types/smc/consultation"><con:IdPRM>19136758109411</con:IdPRM><con:CR><dico:Statut xmlns:dico="http://www.erdfdistribution.fr/linky/types/dico">Rejet</dico:Statut><dico:HorEmission xmlns:dico="http://www.erdfdistribution.fr/linky/types/dico">2015-02-17T14:32:03.887+01:00</dico:HorEmission><dico:Detail xmlns:dico="http://www.erdfdistribution.fr/linky/types/dico"><dico:Code>REJ016</dico:Code></dico:Detail></con:CR></con:Reponse></soap:Body></soap:Envelope>
--------------------------------------
My code doesnt do this, it makes something like clustering in the same line :(
This is my code :
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use Time::Piece;
my $num_args = $#ARGV + 1;
if ($num_args != 2) {
print "\nUsage: Modif_Log.pl inputDirectory outputDirectory\n";
exit;
}
my $inputDirectory=$ARGV[0];
my $outputDirectory=$ARGV[1];
my #liste = glob($inputDirectory."*.log*");
my $today = localtime->strftime('%d%m');
foreach my $s (#liste){
my $inbound ="";
my $outbound ="";
my $id ="";
my $encoding ="";
my $httpMethod ="";
my $contentType ="";
my $headers ="";
my $payload ="";
my $responseCode ="";
my $theAdress ="";
my $others ="";
open ( FILE, $inputDirectory.basename($s) ) || die "can't open file!";
if (-M $inputDirectory.basename($s) < 1 && $s =~ $today) {
print "Processing ".$s."\n";
my #lines = <FILE>;
close (FILE);
my $outputFileName = basename($s);
$outputFileName =~ s/_[0-9]{6}//;
open(my $outputFile, '>', $outputDirectory.$outputFileName) or die "can't open file!";
foreach my $line (#lines) {
chomp($line);
if ($line =~ /Inbound/i) { $inbound .= $line."|"; }
elsif ($line =~ /Outbound/i) { $outbound .= $line."|"; }
elsif ($line =~ /^ID:/) { $id .= $line."|"; }
elsif ($line =~ /^Encoding :/) { $encoding .= $line."|"; }
elsif ($line =~ /^Http-Method:/) { $httpMethod .= $line."|"; }
elsif ($line =~ /^Content-Type:/) { $contentType .= $line."|"; }
elsif ($line =~ /^Headers:/) { $headers .= $line."|"; }
elsif ($line =~ /^Payload:/) { $payload .= $line."|"; }
elsif ($line =~ /^Response-Code:/) { $responseCode .= $line."|"; }
elsif ($line =~ /^Address:/) { $theAdress .= $line."|"; }
elsif ($line !~ /--/) { $others .= $line."|"; }
else { ; }
}
if ($inbound ne "") { print $outputFile $inbound."\n"; }
if ($outbound ne "") { print $outputFile $outbound."\n"; }
if ($id ne "") { print $outputFile $id."\n"; }
if ($encoding ne "") { print $outputFile $encoding."\n"; }
if ($httpMethod ne "") { print $outputFile $httpMethod."\n"; }
if ($contentType ne "") { print $outputFile $contentType."\n"; }
if ($headers ne "") { print $outputFile $headers."\n"; }
if ($payload ne "") { print $outputFile $payload."\n"; }
if ($responseCode ne "") { print $outputFile $responseCode."\n"; }
if ($theAdress ne "") { print $outputFile $theAdress."\n"; }
if ($others ne "") { print $outputFile $others."\n"; }
close $outputFile;
print "Finished Processing ".$s."\n";
} else {
print $s." is older than one day\n";
}
}
Can you please help me ? Perl is turning me creasy
Remove bunch of if-statements and change your forloop as following:
my $buf = q{};
my $last = q{};
my $sep_count = 0;
my $line_number = 0;
foreach my $line (#lines) {
# remove CRLF, chomp only eliminate LF
$line =~ s/\R+//;
$line_number++;
if ($line =~ /^-+$/) {
# if the line is a separator
$sep_count++;
if ($sep_count & 1) {
# begin sep ($sep_count is an odd number)
$buf = $last;
}
else {
# end sep ($sep_count is an even number)
print {$outputFile} "$buf\n";
}
}
else {
if ($sep_count & 1) {
$buf .= ' | ' . $line;
}
else {
# flush $last except for the first line
print {$outputFile} "$last\n" if $line_number != 1;
}
# keep last line (INFO...) to concat
$last = $line;
}
}
print {$outputFile} "$last\n";
Your list of strings are just values that must appear in a line of the input file for it to be included in the output. There is no need to store lines in different variables according to which criterion it matched
This program appears to do what you need. It builds a regular expression from the list of strings so that they can all be tested in a single match. The lines to be printed are accumulated in array #output and printed to the output file when the whole input file has been processed
Note that I've used rel2abs to append a file name to a directory. It takes account of several cases that simple string concatenation doesn't allow for, as well as making the code clearer
I haven't been able to test this except to make sure that it compiles
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use Time::Piece;
use File::Spec::Functions 'rel2abs';
if ( #ARGV != 2 ) {
die "\nUsage: Modif_Log.pl input_dir output_dir\n";
}
my ( $input_dir, $output_dir ) = #ARGV;
my $today = localtime->strftime('%d%m');
my #liste = glob rel2abs( '*.log*', $input_dir );
my #wanted = (
qr/Inbound/i,
qr/Outbound/i,
qr/^ID:/,
qr/^Response-Code:/,
qr/^Encoding :/,
qr/^Http-Method:/,
qr/^Content-Type:/,
qr/^Headers:/,
qr/^Payload:/,
qr/^Address:/,
);
my $wanted = join '|', #wanted;
$wanted = qr/(?:$wanted)/;
for my $input_file ( #liste ) {
unless ( -M $input_file < 1 and $input_file =~ $today ) {
warn qq{"$input_file" is older than one day\n};
next;
}
warn qq{Processing "$input_file"\n};
open my $in_fh, '<', $input_file die qq{Unable to open "$input_file" for input: $!};
my #output;
while ( <$fh> ) {
next unless /$wanted/;
chomp;
push #output, $_;
}
my $output_file_name = basename($input_file);
$output_file_name =~ s/_[0-9]{6}//;
my $output_file = rel2abs($output_file_name, $output_dir);
open my $out_fh, '>', $output_file
or die qq{Unable to open "$output_file" for output: $!};
print $out_fh join(' | ', #output), "\n";
warn qq{Finished Processing "$input_file"\n};
}
Hello I've multiple sequences in stockholm format, at the top of every alignment there is a accession ID, for ex: '#=GF AC PF00406' and '//' --> this is the end of the alignment. When I'm converting the stockholm format to fasta format I need PF00406 in the header of every sequence of the particular alignment. Some times there will be multiple stockholm alignments in one file. I tried to modify the following perl script, it gave me bizarre results, any help will be greatly appreciated.
my $columns = 60;
my $gapped = 0;
my $progname = $0;
$progname =~ s/^.*?([^\/]+)$/$1/;
my $usage = "Usage: $progname [<Stockholm file(s)>]\n";
$usage .= " [-h] print this help message\n";
$usage .= " [-g] write gapped FASTA output\n";
$usage .= " [-s] sort sequences by name\n";
$usage .= " [-c <cols>] number of columns for FASTA output (default is $columns)\n";
# parse cmd-line opts
my #argv;
while (#ARGV) {
my $arg = shift;
if ($arg eq "-h") {
die $usage;
} elsif ($arg eq "-g") {
$gapped = 1;
} elsif ($arg eq "-s"){
$sorted = 1;
} elsif ($arg eq "-c") {
defined ($columns = shift) or die $usage;
} else {
push #argv, $arg;
}
}
#ARGV = #argv;
my %seq;
while (<>) {
next unless /\S/;
next if /^\s*\#/;
if (/^\s*\/\//) { printseq() }
else {
chomp;
my ($name, $seq) = split;
#seq =~ s/[\.\-]//g unless $gapped;
$seq{$name} .= $seq;
}
}
printseq();
sub printseq {
if($sorted){
foreach $key (sort keys %seq){
print ">$key\n";
for (my $i = 0; $i < length $seq{$key}; $i += $columns){
print substr($seq{$key}, $i, $columns), "\n";
}
}
} else{
while (my ($name, $seq) = each %seq) {
print ">$name\n";
for (my $i = 0; $i < length $seq; $i += $columns) {
print substr ($seq, $i, $columns), "\n";
}
}
}
%seq = ();
}
Depending on the how much variation there is in the line with the accessionID, you might need to modify the regex, but this works for your example file
my %seq;
my $aln;
while (<>) {
if ($_ =~ /#=GF AC (\w+)/) {
$aln = $1;
}
elsif ($_ =~ /^\s*\/\/\s*$/){
$aln = '';
}
next unless /\S/;
next if /^\s*\#/;
if (/^\s*\/\//) { printseq() }
else {
chomp;
my ($name, $seq) = split;
$name = $name . ' ' . $aln;
$seq{$name} .= $seq;
}
}
printseq();
I have an ftp upload from my client machine to my server running consistently as a means of backup, occasionally if the connection becomes corrupt the upload will stall, the solution to this is to remove the "corrupt file" from the server, then the client resumes and the file is uploaded next time the client runs. This script is to remove the file if it has never occured before, or check the time stamp if it has been deleted in the past and check that this is a new occurence. Then delete if required.
the line in the logfile will be like:
Sun May 11 02:38:46 2010 [pid 17116] [ftp] FAIL UPLOAD: Client "192.168.179.58", "/Dan/Example.file", 0.00Kbyte/sec
and once written to the filelist it looks like this:
Sun May 11 02:38:46 - /Dan/Example.file
Below you can see where the scope problem lies within the read_filelist() sub-routine.
Please see the solution so far:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper qw(Dumper);
#open /var/log/vsftpd.log read only, and /var/log/vsftpd.log R/W + append
open my $logfile, '<', '/var/log/vsftpd.log' # 3 arg open is safer
or die "could not open file: $!"; # checking for errors is good
open my $filelist, '+<', '/scripts/filelist'
or die "could not open file: $!";
my #rid;
my #filename;
my #deletedfile;
my $int = -1;
my #time;
my #hourcompare;
my #splittime;
my #filelisttime;
my #splitfilelisttime;
my #filelistfile;
my #filelistarray;
my $fileexists = 0;
#Define read_filelist()
sub read_filelist{
my ($filename, $hour, $min, $sec, $filelist) = #_;
while (<$filelist>){
#filelisttime = split /\s+/, $_;
#splitfilelisttime = split /:/, $filelisttime[3];
#filelistfile = split /\s+-\s+/, $_;
my $fsec = $splitfilelisttime[2]+0;
my $fmin = $splitfilelisttime[1]+0;
my $fhour = $splitfilelisttime[0]+0;
if ($filelistfile[2] eq $filename){
my $fileexists = 1;
if ($hour >= $fhour){
if($min >= $fmin){
if($sec > $fsec){
system ("rm", "-fv", "/home/desktop"."$filename");
}
}
}
}
}
}
#open vsftp log and look for lines that include "FAIL UPLOAD" print those lines to a file
while (<$logfile>) {
$int = $int + 1;
if (index($_, "FAIL UPLOAD:") != -1){
#rid = split /\s+"/, $_;
#filename = split /",/, $rid[2];
#time = split /\s+201/, $rid[0];
}
$deletedfile[$int] = $filename[0];
if ($filename[0] ne $deletedfile[$int-1]){
print $filelist $time[0]." - ".$filename[0]."\n";
}
#convert the timestamp into integers for comparison
#hourcompare = split /\s+/, $time[0];
#splittime = split /:/, $hourcompare[3];
my $sec = $splittime[2]+0;
my $min = $splittime[1]+0;
my $hour = $splittime[0]+0;
#itterate through '/scripts/filelist'
read_filelist($filename[0], $hour, $min, $sec, $filelist);
if ($fileexists = 0){
system ("rm", "-fv", "/home/desktop"."$filename[0]");
}
}
close $filelist;
close $logfile;
the variables pass to the read_filelist() sub no problem, but when I start the while() loop all passed variables become uninitialized:
sub read_filelist {
my ($filename, $hour, $min, $sec, $filelist) = #_;
while (<$filelist>) {
#filelisttime = split /\s+/, $_;
#splitfilelisttime = split /:/, $filelisttime[3];
#filelistfile = split /\s+-\s+/, $_;
my $fsec = $splitfilelisttime[2]+0;
my $fmin = $splitfilelisttime[1]+0;
my $fhour = $splitfilelisttime[0]+0;
if ($filelistfile[2] eq $filename) {
my $fileexists = "T";
if ($hour >= $fhour) {
if($min >= $fmin) {
if($sec > $fsec) {
system ("rm", "-fv", "/home/desktop"."$filename");
}
}
}
}
print "log: " . "$hour" . ":" . "$min" . ":" . "$sec" . "\n";
print "file: " . "$fhour" . ":" . "$fmin" . ":" . "$fsec" . "\n";
print "$filename" . "\n";
}
}
read_filelist($filename[0], $hour, $min, $sec, $filelist);
This returns the following:
Use of uninitialized value in string eq at removefailed.pl line 39, <$filelist> line 1.
Use of uninitialized value $filename in string eq at removefailed.pl line 39, <$filelist> line 1.
log: 0:0:0
file: 2:38:46
Use of uninitialized value $filename in string at removefailed.pl line 52, <$filelist> line 1.
However if I move the prints outside of the while loop it works, but obviously I can only compare them with the last line of the filelist.
sub read_filelist {
my ($filename, $hour, $min, $sec, $filelist) = #_;
print "log: " . "$hour" . ":" . "$min" . ":" . "$sec" . "\n";
while (<$filelist>) {
#filelisttime = split /\s+/, $_;
#splitfilelisttime = split /:/, $filelisttime[3];
#filelistfile = split /\s+-\s+/, $_;
my $fsec = $splitfilelisttime[2]+0;
my $fmin = $splitfilelisttime[1]+0;
my $fhour = $splitfilelisttime[0]+0;
if ($filelistfile[2] eq $filename) {
my $fileexists = "T";
if ($hour >= $fhour) {
if($min >= $fmin) {
if($sec > $fsec) {
system ("rm", "-fv", "/home/desktop"."$filename");
}
}
}
}
print "file: " . "$fhour" . ":" . "$fmin" . ":" . "$fsec" . "\n";
}
print "$filename" . "\n";
}
read_filelist($filename[0], $hour, $min, $sec, $filelist);
I get the following output:
file: 2:38:46
log: 2:38:46
/Dan/Example.file
Any help with this would be much appreciated, please let me know if you need any further information?
I have solved this problem using Hash's. I think this was caused because the filelist was already open in the logfile read.
Anyhow I created a global Hash:
my %logfilelines;
passed all the assorted relevant lines to it from the logfile:
$logfilelines{$filename[0].":".$hour.":".$min.":".$sec}++
Then within the read_file() sub I run through %logfilelines; and compare the filename\ time etc. I will have to rebuild the time comparison as it is wrong but atleast I am making progress now. see the new subroutine below in case you are curious:
sub read_filelist{
#my ($filename, $hour, $min, $sec, $filelist) = #_;
my $fint = -1;
my #filelines;
my #filelistlines;
foreach my $line (keys %logfilelines) {
open my $filelist2, '<', 'c:\scripts\filelist'
or die "could not open file: $!";
$fint = $fint + 1;
$filelines[$fint] = $line;
#filelistlines = split /:/, $filelines[$fint];
my $filename = $filelistlines[0];
my $hour = $filelistlines[1]+0;
my $min = $filelistlines[2]+0;
my $sec = $filelistlines[3]+0;
while (<$filelist2>){
my #filelisttime = split /\s+/, $_;
my #splitfilelisttime = split /:/, $filelisttime[3];
my #filelistfile = split /-\s+/, $_;
my $fsec = $splitfilelisttime[2]+0;
my $fmin = $splitfilelisttime[1]+0;
my $fhour = $splitfilelisttime[0]+0;
chomp $filelistfile[1];
if ($filelistfile[1] eq $filename){
# my $fileexists = 1;
print "log: "."$hour".":"."$min".":"."$sec"." $filename"."\n";
print "file: "."$fhour".":"."$fmin".":"."$fsec"."\n";
if ($min > $fmin || $hour > $fhour){
# if($min >= $fmin ||$hour >= $fhour){
# if($sec > $fsec){
#system ("rm", "-fv", "/home/desktop"."$filename");
print "success"." $filename";
# }
# }
}
}
}
}
Can you show me how to create a subroutine or function using this code?
Basically I want to make my code into a subroutine so I'll be able to re-use it without making my script too long.
Here is my script:
#!/usr/local/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Carp qw(croak);
my #fields;
my ($tmp_var, $rec_type, $country, $header, $Combline, $records, $line);
my $filename = 'data5.txt';
open (my $input_fh, '<', $filename ) or croak "Can't open $filename: $!";
open my $OUTPUTA, ">", 'drp1.txt' or die $!;
open my $OUTPUTB, ">", 'drp2.txt' or die $!;
while (<$input_fh>) {
$line = _trim($_);
#fields = split (/\|/, $line);
$rec_type = $fields[0];
$country = $fields[1];
my $string = substr $fields[1], 0, 1;
$header = $line if(/^INVHDR/);
if ($rec_type eq 'INVDET') {
if ($string eq 'I') {
$records = $header . $line;
print $OUTPUTA $records, scalar <$input_fh>;
}
else {
$records = $header . $line;
print $OUTPUTB $records, scalar <$input_fh>;
}
}
}
close $OUTPUTA or die $!;
close $OUTPUTB or die $!;
sub _trim {
my $word = shift;
if ( $word ) {
$word =~ s/\s*\|/\|/g; #remove trailing spaces
$word =~ s/"//g; #remove double quotes
}
return $word;
}
This is the part of the script that I wanted to put in a subroutine or function:
$line = _trim($_);
#fields = split (/\|/, $line);
$rec_type = $fields[0];
$country = $fields[1];
my $string = substr $fields[1], 0, 1;
$header = $line if (/^INVHDR/);
if ($rec_type eq 'INVDET') {
if ($string eq 'I') {
$records = $header . $line;
print $OUTPUTA $records, scalar <$input_fh>;
}
else {
$records = $header . $line;
print $OUTPUTB $records, scalar <$input_fh>;
}
}
I would suggest breaking it out a little differently and expand on your _trim function, turning it into a parse function:
use strict;
use warnings;
open( my $input_fh, '<', 'data5.txt' ) or die "Can't open $filename: $!";
open( my $OUTPUTA, '>', 'drp1.txt' ) or die $!;
open( my $OUTPUTB, '>', 'drp2.txt' ) or die $!;
my $header = '';
while (<$input_fh>) {
if ($_ =~ /^INVHDR/) {
$header = $_;
}
if ($_ =~ /^INVDET/) {
my #data = parse($_);
my $line = $header . join('|', #data);
# scalar <$input_fh> is almost certainly not doing what you expect,
# though I'm not sure what you're try to accomplish with it
if ( $data[1] =~ /^I/ ) {
print $OUTPUTA $line;
} else {
print $OUTPUTB $line;
}
}
}
sub parse {
my $input = shift || return;
my $input =~ s/"//g; # remove double quotes
# Here I've combined the removal of trailing spaces with the split.
my #fields = split( m{\s*\|}, $input );
return #fields;
}