1

I am merging multiple html files in the directory/subdirectory into single html within the same directories. I gone through some website and tried the below code:

#!/usr/bin/perl -w
use strict;
use File::Slurp;
my $basedir = 'c:/test';

opendir(DIR, $basedir) or die $!;
my @files = readdir(DIR); # name arrays plural, hashes singular
closedir DIR;

my $outfilename = 'final.htm';
my $outfilesrc = undef; 

foreach (sort @files){ 
  $outfilesrc.= File::Slurp::slurp("$basedir/$_");
}

open(OUT, "> $basedir/$outfilename") or die ("Can't open for writing: $basedir/$outfilename : $!");
print OUT $outfilesrc;
close OUT;

exit;

But I am getting follwing error and could not merge the file.

read_file 'c:/test.' - sysopen: Permission denied at mergehtml.pl line 15

Can anyone help me! Is there any way to merge HTML files to single in Perl?

VSe
  • 919
  • 2
  • 13
  • 29
  • What, you just want to take N files and mash them together into one file? – TLP Apr 10 '13 at 12:04
  • 1
    I believe the `copy` command in the windows shell can also concatenate files, e.g. `copy file1+file2 allfiles`. See `copy /?` for more information. – TLP Apr 10 '13 at 12:29
  • See also this question http://stackoverflow.com/questions/60244/is-there-replacement-for-cat-on-windows – TLP Apr 10 '13 at 12:36

2 Answers2

5

Your error most likely comes from trying to open the "current directory" c:\test\. for reading. This comes from using readdir to list the files: readdir includes all the files.

If all you want to do is concatenate the files, its rather simple if you're in linux: cat test/* > final.htm. Unfortunately, in Windows its a bit more tricky.

perl -pe"BEGIN { @ARGV = map glob, @ARGV }" "C:/test/*" > final.htm

Explanation:

We use the -p option to read and print the content of the argument file names. Those arguments are in this case a glob, and the windows command shell does not perform these globs automagically, so we have to ask perl to do it, with the built-in glob command. We do this in a BEGIN block to separate it from the rest of the code. The "rest of the code" is in this case just (basically) a while (<>) { print } block that reads and prints the contents of the files. At the end of the line we redirect all the output to the file final.htm.

Why use glob over readdir? Well, for one thing, readdir includes the directories . (current dir) and .. (parent dir), which will mess up your code, like I mentioned at the top. You would need to filter out directories. And glob does this smoothly with no problem.

If you want the longer version of this script, you can do

use strict;
use warnings;

@ARGV = map glob, @ARGV;
while (<>) {
    print;
}

Note that I suspect that you only want html files to be merged. So it would perhaps be a good idea of you to change your glob from * to something like

*.htm *.html
TLP
  • 66,756
  • 10
  • 92
  • 149
  • Hi I tried this but I am getting the below error. Can't do inplace edit: C:/test/ is not a regular file, <> line ... – VSe Apr 11 '13 at 05:13
  • That error comes from using the -i switch (in-place edit). I've never said you should use that, and it would not help anyway. – TLP Apr 11 '13 at 09:55
  • I used the same lines which you mentioned in the longer version of script but can't get the result, getting only error msgs – VSe Apr 11 '13 at 09:58
  • @VSenthil The error suggests that you did `perl -i script.pl c:/test/`, and not `perl script.pl "c:/test/*" > final.htm` like I told you to. – TLP Apr 11 '13 at 10:42
  • Yes @TLP, Now its working fine. But my problem is the files in the subdirectory/maindirecoty merged should be saved seperately and placed in the respective folder.. – VSe Apr 11 '13 at 11:34
  • So you mean you want to recurse through all the subdirectories and merge all files found, once per dir? Well, that's an entirely new question that would be best solved with File::Find instead of glob or readdir. – TLP Apr 11 '13 at 11:49
  • Hi TLP, Can you help me with that – VSe Apr 11 '13 at 11:51
  • This site is about helping people with programming questions, a way to help people grow and learn. It is not about writing ready to use code for free. If I am to write this program for you, I would expect you to pay me for my trouble. – TLP Apr 11 '13 at 11:59
  • Sorry to bother you. I can try and since I am not expert in Perl and its an urgent request I just asked you the help, not asking to give ready to code. Thanks for the help which you did. – VSe Apr 11 '13 at 12:04
  • You can read the documentation for File::Find and re-write your program to be recursive, then ask new questions if you run into trouble. – TLP Apr 11 '13 at 12:07
1

Filter out the files "." and ".." from your @files list.

Dancrumb
  • 26,597
  • 10
  • 74
  • 130