Not getting any output while reading the file - perl

I am trying to read the file from some other directory, it for me every things looks good but unfortunately neither i am getting any error nor any output.
I am working on windows Pc.
Here is My code:
use strict;
use warnings;
use Cwd;
#chdir('C:\\APTscripts\\APStress\\Logs');
chdir('C:\\Mahi_doc\\Apstress_logs');
my ($dir_01,$dir_02);
my #FILES;
$dir_01 = getcwd;
#print "$dir\n";
opendir(DIR_01, $dir_01) ;
#FILES=readdir(DIR_01);
close(DIR_01);
my $count=12;
my $lines;
for my $dir_02 (#FILES)
{
#print"$dir_02\n";
if ( -d $dir_02)
{
opendir (DIR_02, "$dir_01"."/"."$dir_02") ;
while(our $file = readdir(DIR_02))
{
if($file =~ /APStress.*UIlog/g)
{
# print"$file\n";
open(FH,$file) or die "can not open the file $!\n";
while (defined(my $lines = <FH>))
{
print"$lines\n";
if($lines=~ m/WATCHDOG/ || $lines=~ m/Excessive JNI/gi )
{#chks for watchdog/excessive jni issue exist
print "Got it\n";
}
elsif($lines=~ m/installd: eof/gi)
{
print "EOF:Got it \n";
}
}
}
}
}
}

In the open clause, give the full path for the file:
open(FH, "$dir_01/$dir_02/$file") or die "can not open the file $!\n";
and better use 3 arg open and lexical file handler:
open(my $FH, '<', "$dir_01/$dir_02/$file") or die "can not open the file $!\n";

Related

Perl script returning 0 when a file is read

Im just trying to copy a file to a different directory before I process it. Here is the code:
use File::stat;
use File::Copy;
use LWP::UserAgent;
use strict;
use warnings;
use Data::Dumper;
use Cwd qw(getcwd);
my $dir = "\\folder\\music";
my $dir1 = "c:\\temp";
opendir(my $dh, $dir) or die "Cant open directory : $!\n";
#my #list = readdir($dh)
my #files = map { [ stat "$dir/$_", $_ ] }
grep( /Shakira.*.mp3$/, readdir( $dh ) );
closedir($dh);
sub rev_by_date
{
$b->[0]->ctime <=> $a->[0]->ctime
}
my #sorted_files = sort rev_by_date #files;
my #newest = #{$sorted_files[0]};
my $name = pop(#newest);
print "Name: $name\n";
#**********************
#Upto here is working fine
my $new;
open OLD,"<",$name or die "cannot open $old: $!";
from here the problem starts
open(NEW, "> $new") or die "can't open $new: $!";
while ()
{
print NEW $_ or die "can't write $new: $!";
}
close(OLD) or die "can't close $old: $!";
close(NEW) or die "can't close $new: $!";
The error im getting is :
cannot open Shakira - Try Everything (Official Video).mp3: No such file or directory at copy.pl line 49.
when Im chomping the filename, like
my $oldfile = chomp($name);
then the error is :
Name: Shakira - Try Everything (Official Video).mp3
old file is 0
cannot open 0: No such file or directory at copy.pl line 49.
Any idea?
chomp changes its argument in place and returns the number of removed characters. So the correct usage is
chomp(my $oldfile = $name);
Also, you probably wanted
while (<OLD>) {
instead of
while () {
which just loops infinitely.
Moreover, you correctly prepend $dir/ to a filename in the stat call, but you shold do so everywhere.

how to change the contents in the file in perl?

I am trying to open one file read oneline in it at a time then open the another file and try to search for some part of the line read from the first file in the second file and try to replace all instances with the other part of the line read from the first file.When i am executing it its getting executed and i am able to see the result on the console but the files are not getting modified. What could be the mistake. Can some one please suggest this.
use strict;
use warnings;
use autodie; # die if problem reading or writing a file
my $filename = 'compare.txt';
open(my $fh, '+<', $filename) or die "Could not open file '$filename' $!";
while(<$fh>){
my $readline= "$_";
print("\n");
my #arr=split(',',$readline);
print($arr[0]."\n".$arr[1]);
replace($arr[0],$arr[1]);
}
close $fh;
sub replace
{
my $search=shift(#_);
my $replace=shift(#_);
my $filename2 = 'replace.txt';
open(my $fh1, '+<', $filename2) or die "Could not open file '$filename' $!";
while(<$fh1>)
{
my $readline2= "$_";
$readline2=~s/$search/$replace/g;
print($readline2);
print("\n");
}
close $fh1;
}
As a huge fan of the Path::Tiny module, I would do the above as:
use 5.014;
use warnings;
use Path::Tiny;
my %rep = map { split /,/ } path('compare.txt')->lines({chomp => 1});
path("replace.txt")->edit_lines( sub {
while(my($key,$val) = each(%rep)) {
s/$key/$val/g;
}
});
In your sub, when you are iterating the lines in your file, you should write it back to a file. The regex substitute doesn't automatically write it back to file.
use strict;
use warnings;
use autodie; # die if problem reading or writing a file
use File::Copy;
my $filename = 'compare.txt';
open(my $fh, '+<', $filename) or die "Could not open file '$filename' $!";
while(<$fh>){
my $readline= "$_";
print("\n");
my #arr=split(',',$readline);
print($arr[0]."\n".$arr[1]);
replace($arr[0],$arr[1]);
}
close $fh;
sub replace
{
my $search=shift(#_);
my $replace=shift(#_);
my $filename2 = 'replace.txt';
open(my $fh1, '+<', $filename2) or die "Could not open file '$filename' $!";
#open file to write to
open $newfile, '>', 'replace_tmp.txt';
while(<$fh1>)
{
chomp;
my $readline2= "$_";
$readline2=~s/$search/$replace/g;
print( $newfile, $readline2);
print($newfile, "\n");
}
close($fh1);
close($newfile);
move ('replaced.txt', 'replace.txt');
}
This is simple way of doing it. You can use File::Tie to write back to the same file and avoid renaming it, or refer to perldoc

readdir() attempted on invalid dirhandle

What am I doing wrong? I've tried many things but can't seem to read from this file. Thanks!
my $d = 'URLs.txt';
open(my $fh, '<:encoding(UTF-8)', $d)
#opendir(D, "$d") || die "Can't open directory $d: $!\n";
or die "Can't open directory $d: $!\n";
my #list = readdir($fh);
closedir($fh);
foreach my $f (#list) {
my $json_data = get "$f";
my $json_obj = new JSON;
my $URLdata = $json_obj->decode($json_data);
return $URLdata->{'status'} eq 'UP';
}
URLs.txt appears to be a file, not a directory
To open a file, write
open my $fh, '<', $filename or die $!;
and read from it with
while ( my $line = <$fh> ) { ... }
To open a directory, write
opendir my $dh, $dirname or die $!;
and read its contents with
while ( my $item = readdir $dh ) { ... }
If you had use strict and use warnings 'all' in place as you should in every Perl program you write you would have seen
readdir() attempted on invalid dirhandle $fh
closedir() attempted on invalid dirhandle $fh
which would have guided you towards the problem
You may be better of with other functions, depending on what it is you want to do
Your variable names are not great, to put it mildly. Let's fix that!
use strict;
use warnings;
use JSON;
use LWP::Simple;
my $file = 'URLs.txt';
open(my $fh, '<:encoding(UTF-8)', $file) or die "Can't open file $file: $!\n";
chomp(my #lines = <$fh>);
close($fh);
foreach my $url (#lines) {
my $json_text = get($url);
if (defined($json_text)) {
my $perl_ref = decode_json($json_text);
if ($perl_ref->{status} eq 'UP') {
print "foo\n";
}
} else {
# handle the error!
}
}
You'll notice I also:
Added use strict and use warnings, which should be in every Perl file you write
Added error-checking to the LWP get() result
Removed indirect object notation (new JSON) in favor of the decode_json() convenience function. It's the same as JSON->new->utf8->decode(), only shorter.
Removed the return statement, because it doesn't make any sense outside of a subroutine. If this code has actually been yanked from a subroutine, then you should show that as part of your MCVE.

How to read file in Perl and if it doesn't exist create it?

In Perl, I know this method :
open( my $in, "<", "inputs.txt" );
reads a file but it only does so if the file exists.
Doing the other way, the one with the +:
open( my $in, "+>", "inputs.txt" );
writes a file/truncates if it exists so I don't get the chance to read the file and store it in the program.
How do I read files in Perl considering if the file exists or not?
Okay, I've edited my code but still the file isn't being read. The problem is it doesn't enter the loop. Anything mischievous with my code?
open( my $in, "+>>", "inputs.txt" ) or die "Can't open inputs.txt : $!\n";
while (<$in>) {
print "Here!";
my #subjects = ();
my %information = ();
$information{"name"} = $_;
$information{"studNum"} = <$in>;
$information{"cNum"} = <$in>;
$information{"emailAdd"} = <$in>;
$information{"gwa"} = <$in>;
$information{"subjNum"} = <$in>;
for ( $i = 0; $i < $information{"subjNum"}; $i++ ) {
my %subject = ();
$subject{"courseNum"} = <$in>;
$subject{"courseUnt"} = <$in>;
$subject{"courseGrd"} = <$in>;
push #subjects, \%subject;
}
$information{"subj"} = \#subjects;
push #students, \%information;
}
print "FILE LOADED.\n";
close $in or die "Can't close inputs.txt : $!\n";
Use the proper test file operator:
use strict;
use warnings;
use autodie;
my $filename = 'inputs.txt';
unless(-e $filename) {
#Create the file if it doesn't exist
open my $fc, ">", $filename;
close $fc;
}
# Work with the file
open my $fh, "<", $filename;
while( my $line = <$fh> ) {
#...
}
close $fh;
But if the file is new (without contents), the while loop won't be processed. It's easier to read the file only if the test is fine:
if(-e $filename) {
# Work with the file
open my $fh, "<", $filename;
while( my $line = <$fh> ) {
#...
}
close $fh;
}
You can use +>> for read/append, creates the file if it doesn't exist but doesn't truncate it:
open(my $in,"+>>","inputs.txt");
First check whether the file exists or not. Check the sample code below :
#!/usr/bin/perl
use strict;
use warnings;
my $InputFile = $ARGV[0];
if ( -e $InputFile ) {
print "File Exists!";
open FH, "<$InputFile";
my #Content = <FH>;
open OUT, ">outfile.txt";
print OUT #Content;
close(FH);
close(OUT);
} else {
print "File Do not exists!! Create a new file";
open OUT, ">$InputFile";
print OUT "Hello World";
close(OUT);
}

merging two files using perl keeping the copy of original file in other file

I have to files like A.ini and B.ini ,I want to merge both the files in A.ini
examples of files:
A.ini::
a=123
b=xyx
c=434
B.ini contains:
a=abc
m=shank
n=paul
my output in files A.ini should be like
a=123abc
b=xyx
c=434
m=shank
n=paul
I want to this merging to be done in perl language and I want to keep the copy of old A.ini file at some other place to use old copy
A command line variant:
perl -lne '
($a, $b) = split /=/;
$v{$a} = $v{$a} ? $v{$a} . $b : $_;
END {
print $v{$_} for sort keys %v
}' A.ini B.ini >NEW.ini
How about:
#!/usr/bin/perl
use strict;
use warnings;
my %out;
my $file = 'path/to/A.ini';
open my $fh, '<', $file or die "unable to open '$file' for reading: $!";
while(<$fh>) {
chomp;
my ($key, $val) = split /=/;
$out{$key} = $val;
}
close $fh;
$file = 'path/to/B.ini';
open my $fh, '<', $file or die "unable to open '$file' for reading: $!";
while(<$fh>) {
chomp;
my ($key, $val) = split /=/;
if (exists $out{$key}) {
$out{$key} .= $val;
} else {
$out{$key} = $val;
}
}
close $fh;
$file = 'path/to/A.ini';
open my $fh, '>', $file or die "unable to open '$file' for writing: $!";
foreach(keys %out) {
print $fh $_,'=',$out{$_},"\n";
}
close $fh;
The two files to be merged can be read in a single pass and don't need to be treated as separate source files. That allows the use of <> to read all files passed as parameters on the command line.
Keeping a backup copy of A.ini is simply a matter of renaming it before writing the merged data to a new file of the same name.
This program appears to do what you need.
use strict;
use warnings;
my $file_a = $ARGV[0];
my (#keys, %values);
while (<>) {
if (/\A\s*(.+?)\s*=\s*(.+?)\s*\z/) {
push #keys, $1 unless exists $values{$1};
$values{$1} .= $2;
}
}
rename $file_a, "$file_a.bak" or die qq(Unable to rename "$file_a": $!);
open my $fh, '>', $file_a or die qq(Unable to open "$file_a" for output: $!);
printf $fh "%s=%s\n", $_, $values{$_} for #keys;
output (in A.ini)
a=123abc
b=xyx
c=434
m=shank
n=paul