For each xml file in a directory, how to add its contents to another file at a certain place?
I have a fun and seemingly simple Perl challenge that is stumping my colleagues. Care to take a crack? It will really help my project move forward.
Iterate through each xmlfileXF in directoryD, and for each one:
- in modifythisfileMTF, copy wordblockWB and paste it after the last wordblockWB.
- in modifythisfileMTF, replace replacemeRM with the contents of the current xmlfileXF.
directoryD only has xml files by the way, so really, you don't have to discriminate on filetype. Also, it's fine to hardcode the contents of wordblockWB if you prefer.
modifythisfileMTF.txt contents:
myfunc
{
// begin wordblockWB
prewords
"msg"=replacemeRM
postwords
// end wordblockWB
return 0;
}
directoryD contents:
xmlfileXF1.xml
xmlfileXF2.xml
...6000 more
xmlfileXF1.xml contents:
<foo/>
xmlfileXF2.xml contents:
<bar/>
desired output modifythisfileMTF.txt cont开发者_运维问答ents:
myfunc
{
// begin wordblockWB
prewords
"msg"=<foo/>
postwords
// end wordblockWB
// begin wordblockWB
prewords
"msg"=<bar/>
postwords
// end wordblockWB
return 0;
}
Thanks for all help, and have fun!
This should do the job. It prints to STDOUT, so just redirect to a file as needed.
#!/usr/bin/perl
use strict;
use warnings;
my $directoryD = "/xml files";
my $prewords = "Four score and...\n";
my $postwords = "The End\n";
chdir("$directoryD") or die $!;
opendir(D, ".") or die $!;
my @xmlFiles = grep(/\.xml$/i, readdir(D));
closedir(D);
if (scalar(@xmlFiles) == 0) {
die "Could not detect any XML files in $directoryD\n";
}
print "myfunc\n";
print "{\n";
foreach my $file (@xmlFiles) {
# Read the FIRST line from each file. Ignore any other lines.
open(F, "$file") or die $!;
my $line = <F>;
chomp $line;
close(F);
print $prewords;
print "\"msg\"=$line\n";
print $postwords;
print "\n";
}
print "return 0;\n";
print "}\n";
Here's another possible solution that prints to stdout:
#!/usr/bin/env perl
use strict;
use warnings;
my $dir = shift || '.';
doit(sub {
my $callback = shift;
opendir(my $dh, $dir) or die $!;
while(my $file = readdir($dh)) {
next unless $file =~ /\.xml$/i;
open (my $fh, '<', $file) or die $!;
chomp(my $line = <$fh>);
close($fh) or die $!;
$callback->($line);
}
closedir($dh) or die $!;
});
sub doit {
my $process_files = shift;
print "myfunc\n{\n";
$process_files->(sub {
my $msg = shift;
print join "\n", map { "\t$_" } (
'// begin wordblockWB',
'prewords',
qq{"msg"=$msg},
'postwords',
'// end wordblockWB',
"\n"
);
});
print "\treturn 0;\n}\n";
}
It's a bit verbose but the idea was to keep the file processing code and formatting/output code separate. The extra complexity might not be worth it in this situation though.
精彩评论