Richard Rublev Richard Rublev - 6 months ago 25
Perl Question

How to split xml file with perl?

My code

use strict;

use warnings;

my $filename = '263.xml';

open(my $fh, $filename)

perl -p -i -e '$fh if /<caldata chopper="on"/ "(\d+)"/; print $fh;'


Warning: Use of "-p" without parentheses is ambiguous at line 7.
syntax error at line 7, near ")

perl "
Execution of aborted due to compilation errors.

I want to separate line with

caldata chopper="on"

and caldata chopper="off"
into separate files.
This is the whole line

<caldata chopper="on" gain_1="0" gain_2="0" gain_3="0" impedance="(0,0)">


To clarify why the posted code "doesn't make sense", perl -p -i -e is something you would type on the command line by itself, not something which goes into a Perl program. Basically, the perl -p -i -e '...' is itself the program to run. perldoc perlrun explains in greater detail, but:

  • -p puts a loop around the ... code which runs it against each line of the input file
  • -i means to edit the input file in place (instead of creating any new files for output)
  • -e tells perl that you're providing executable code as part of the command line, rather than running a program from a file

The correct way to do what you were attempting would be something like (warning - untested code):

#!/usr/bin/env perl

use strict;
use warnings;

open my $in, '<', '263.xml' or die "Can't open input file: $!";
open my $out_on, '>', 'on.xml' or die "Can't open 'on' output file: $!";
open my $out_off, '>', 'off.xml' or die "Can't open 'off' output file: $!";

while (my $line = <$in>) {
  $line =~ /<caldata chopper="(on|off)"/;
  if ($1 eq 'on') {
    print $out_on, $line;
  } elsif ($1 eq 'off') {
    print $out_off, $line;

Note, however, that this technique will not create proper XML output files. It will just generate files containing lists of caldata elements without any of the additional surrounding elements needed to have a single, well-formed XML document. If you need a well-formed XML document, I would suggest taking a look at XML::Twig rather than attempting to parse or generate XML by hand.