开发者

For each xml file in a directory, how to add its contents to another file at a certain place?

开发者 https://www.devze.com 2023-03-04 23:43 出处:网络
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.

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:

  1. in modifythisfileMTF, copy wordblockWB and paste it after the last wordblockWB.
  2. 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消