Click here to Skip to main content
15,890,043 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
i tried to read the text file with command line aruments and passing it in subroutine but it throws an error using perl?

Error:

Use of uninitialized value in opendir at ./generate.pl line 50.
Use of uninitialized value in concatenation (.) or string at ./generate.pl line 50.
Can't open : No such file or directory at ./generate.pl line 50.


Execution should be as follows:

./generate.pl -prjroot "/home/rpsa/EMO/ct_space" -outdir "/home/rpsa/output" -mapfile "/home/rpsa/EMO/mapfile.txt"


What I have tried:

#!/usr/local/bin/perl
use strict;
use warnings 'all';
#use CGI qw(:all);
#generate the user file arguments

use File::Path       qw( make_path );
use File::Copy  qw( copy move);
use File::Find::Rule qw( );
use File::Remove();
use Cwd qw(getcwd);
use File::Basename;
use File::Copy ();
use File::Remove();
use File::Basename;
 
 use Getopt::Long 'GetOptions';
GetOptions(
    'prjroot=s' => \my $input_dir,
    'outdir=s'  => \my $output_dir,
   'mapfile=s' => \my $mapfile,
);
##COPYING THE CONFIG FILES FROM SOURCE TO DESTINATION### 
my %created;
for my $in (
   File::Find::Rule
   ->file()
   ->name(qr/^[^.].*\.config$/)
   ->in($input_dir)
) {
   my $match_file = substr($in, length($input_dir) + 1); 
   my ($match_dir) = $match_file =~ m{^(.*)/} ? $1 : '.';
   my $out_dir = $output_dir . '/' . $match_dir;
   my $out     = $output_dir . '/' . $match_file;
   make_path($out_dir) if !$created{$out_dir}++;
   copy($in, $out);
}
##READ THE TEXT FILE AND RENAME THE DIRECTORIES ####
my $dir_map = read_map($ARGV[2]);
print $dir_map;
#my $top_dir = '.';
my $top_dir=$ARGV[1];

rename_dirs( $top_dir, $dir_map );

 sub rename_dirs {
 #print "process started for renaming directories";
    my ( $top_dir, $dir_map ) = @_;

    opendir (my $dh, $top_dir) or die "Can't open $top_dir: $!";
    my $save_dir = getcwd();
    chdir $top_dir;
    while (my $dir = readdir $dh) {
        next if ($dir eq '.') or ($dir eq '..'); 
        if ( exists $dir_map->{$dir} ) {
            my $new_name = $dir_map->{$dir};
            #say "$save_dir: rename $dir $new_name";
            File::Copy::move( $dir, $new_name )
                or die "Could not rename '$dir' as '$new_name': $!";
            $dir = $new_name;
        }
        rename_dirs( $dir, $dir_map ) if -d $dir;

    }
    chdir $save_dir;

}
##SUB ROUTINE TO READ THE TEXT FILE FROM COMMAND LINE ARGUMENTS##
sub read_map {
#print "read the text file \n";
    my ( $fn ) = @_;

    my %dir_map;

    open( my $fh, '<', $ARGV[2] ) or die "Could not open file '$fn': $!";
    while( my $line = <$fh> ) {
        chomp $line;
        my @fields = split /:/, $line;
        if ( @fields == 3 ) {
            $dir_map{$fields[2]} = $fields[1];
        }
    }
    close $fh;
    return \%dir_map;
}
Posted
Updated 5-Mar-17 23:34pm
v5
Comments
Jochen Arndt 6-Mar-17 4:23am    
You should show the code around line 50 (and indicate that line).
What you have shown is not the code that generates the error because that does not contain a call to opendir().
example file 6-Mar-17 4:32am    
i had updated my code.can you review it now
Jochen Arndt 6-Mar-17 4:54am    
The variable $top_dir is not initialised.
Maybe you have called your script without comamnd line arguments ($ARGV[1] is not set).
Richard MacCutchan 6-Mar-17 4:37am    
    opendir (my $dh, $top_dir) or die "Can't open $top_dir: $!";

What is the value of $dh?
example file 6-Mar-17 4:41am    
$dh is the file handle name will store the contents from the $top_dir(i.e current location i should pass it as command line arguments in which the input should take from execution path [i.e -outdir "/home/rpsa/output"].

1 solution

You are using GetOptions at one place and access command line arguments via $ARGV at other places. When using GetOptions, all matching arguments are removed from $ARGV[].

So when executing the script with
./generate.pl -prjroot "/home/rpsa/EMO/ct_space" -outdir "/home/rpsa/output" -mapfile "/home/rpsa/EMO/mapfile.txt"
there will be only $ARGV[0] left (the executed command).

Solution:
Replace all usages of $ARGV[] by the matching variables set by GetOptions.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900