9

I am having a perl script in which i am giving path to directory as input. Directory has xml files inside it.

In my code i am iterating through all the xml files and creating absolute path for all xml files. Code is working fine.

#!/usr/bin/perl

use File::Spec;

$num_args = $#ARGV + 1;
if ($num_args != 1) {
   print "\nUsage: $0 <input directory>\n";
   exit;
}

my $dirPath = $ARGV[0];

opendir(DIR, $dirPath);
my @docs = grep(/\.xml$/,readdir(DIR));

foreach my $file (@docs) 
{
   my $abs_path = join("",$dir,$file);

   print "absolute path is $abs_path";
}

Question i have here is, joining $dirPath and $file with no separator which means that $dirPath must end in a "/". So is there any way or built in function in perl which take cares of this condition and replaces the join method.

All i want is not to worry about the separator "/". Even if script is called with path as "/test/dir_to_process" or "/test/dir_to_process/", i should be able to produce the correct absolute path to all xml files present without worrying about the separator.

Let me know if anyone has any suggestions.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
user1188611
  • 945
  • 2
  • 14
  • 38
  • 5
    When you accepted my previous answer (http://stackoverflow.com/a/28503335/725418) about the same code, I assumed that you understood my comments about the code (which, by the way makes this question redundant). When reading your code now, I see that you did not use *anything* of what I said, not even to use strict and warnings. Was there something you did not understand? – TLP Feb 15 '15 at 19:52

3 Answers3

14

Please take heed of the advice you are given. It is ridiculous to keep asking questions when comments and answers to previous posts are being ignored.

You must always use strict and use warnings at the top of every Perl program you write, and declare every variable using my. It isn't hard to do, and you will be reprimanded if you post code that doesn't have these measures in place.

You use the File::Spec module in your program but never make use of it. It is often easier to use File::Spec::Functions instead, which exports the methods provided by File::Spec so that there is no need to use the object-oriented call style.

catfile will correctly join a file (or directory) name to a path, doing the right thing if path separators are incorrect. This rewrite of your program works fine.

#!/usr/bin/perl

use strict;
use warnings;

use File::Spec::Functions 'catfile';

if (@ARGV != 1) {
   print "\nUsage: $0 <input directory>\n";
   exit;
}

my ($dir_path) = @ARGV;
my $xml_pattern = catfile($dir_path, '*.xml');

while ( my $xml_file = glob($xml_pattern) ) {
   print "Absolute path is $xml_file\n";
}
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • yes i did took the advice given to me in previous posts. Reason i did not included libraries is because was trying to show only the area of code which needed answer (but from now on i will make sure warning/strict) libraries are always included) . My actual script is bigger and more complicated then what i have shown above. Sorry for confusion. Yes i got the answer and it worked fine using catfile. Thanks for helping – user1188611 Feb 15 '15 at 23:11
  • @user1188611: It is strange to leave out `use strict` but include `#!/usr/bin/perl`! I'm glad you found your answer. – Borodin Feb 15 '15 at 23:24
6

The answer is in the documentation for File::Spec, e.g., catfile:

 $path = File::Spec->catfile( @directories, $filename );

or catpath:

 $full_path = File::Spec->catpath( $volume, $directory, $file );
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
0

This will add the trailing slash if not there:

$dirPath =~ s!/*$!/!;
JonB
  • 836
  • 1
  • 11
  • 15