rormonk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!

I'm trying to write a script that compares File A and File B line by line. But when comparing it only takes into account the first 3 characters of every line and ignores the others. When the first 3 characters are absent on a file it skips a line to align it with the other file. The line absent on a file is written to another new file.

Example:

File A     File B

111 abc     111 pqr

111 def     111 stu

222 ghi     111 vwx

223 jkl     222 yza

345 mno    345 bcd

_________________

Output should be:

File A     File B

111 abc     111 pqr

111 def     111 stu

                  111 vwx

222 ghi     222 yza

223 jkl

345 mno     345 bcd

_________________

File that is created:

111 vwx

223 jkl

I'm having a hard time figuring out how to do this. Please Help!

Replies are listed 'Best First'.
Re: Comparing two files and editing it.
by choroba (Cardinal) on Jul 30, 2015 at 13:18 UTC
    Are the lines in the two files sorted by the first three characters? Your sample seems to indicate so. If not, the problem is harder - if there's a mismatch, you don't know on what side the information is missing.
    #!/usr/bin/perl use strict; use warnings; open my $A, '<', 'A' or die $!; open my $B, '<', 'B' or die $!; open my $NEW, '>', 'C' or die $!; my ($lineA, $lineB); while (! eof $A && ! eof $B) { chomp($lineA //= <$A>); chomp($lineB //= <$B>); my ($keyA, $keyB) = map { substr $_, 0, 3 } $lineA, $lineB; if ($keyA eq $keyB) { print "$lineA\t$lineB\n"; undef $lineA; undef $lineB; } elsif ($keyA lt $keyB) { print "$lineA\n"; print {$NEW} "$lineA\n"; undef $lineA; } else { print "\t$lineB\n"; print {$NEW} "$lineB\n"; undef $lineB; } }
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Comparing two files and editing it.
by Anonymous Monk on Jul 30, 2015 at 14:56 UTC

    It's a "diff" problem :)

    #!/usr/bin/perl # http://perlmonks.org/?node_id=1136858 use Algorithm::Diff qw(traverse_sequences); use strict; use warnings; my $FileA = <<END; 111 abc 111 def 222 ghi 223 jkl 345 mno END my $FileB = <<END; 111 pqr 111 stu 111 vwx 222 yza 345 bcd END my @bigA = $FileA =~ /.*\n/g; my @bigB = $FileB =~ /.*\n/g; traverse_sequences( [ map /(...)/, @bigA ], [ map /(...)/, @bigB ], { DISCARD_A => sub { print $bigA[shift] }, DISCARD_B => sub { print $bigB[pop] }, } );
Re: Comparing two files and editing it.
by Anonymous Monk on Jul 31, 2015 at 00:41 UTC

    I'm not sure I understand exactly what you want as output, here's an alternate.

    #!/usr/bin/perl # http://perlmonks.org/?node_id=1136858 use Algorithm::Diff qw(traverse_sequences); use strict; use warnings; my @bigA = split /\n/, <<END; 111 abc 111 def 222 ghi 223 jkl 345 mno END my @bigB = split /\n/, <<END; 111 pqr 111 stu 111 vwx 222 yza 345 bcd END my @newfile; traverse_sequences( [ map /(...)/, @bigA ], [ map /(...)/, @bigB ], { MATCH => sub { print "$bigA[shift] $bigB[pop]\n" }, DISCARD_A => sub { push @newfile, my $left = $bigA[shift] . "\n"; print $left; }, DISCARD_B => sub { push @newfile, my $right = $bigB[pop] . "\n"; print ' ' x 10, $right; }, } ); print "\n\n", @newfile; #use File::Slurp; write_file 'newfilename', @newfile; # to make newfil +e