Nijin
Nijin

Reputation: 41

Compare two files and write the lines from second file to first file

I Have two files name test1 and test2. The contents of the files are as follows.

test1

nijin:qwe123
nijintest:qwerty
nijintest2:abcsdef
nijin2:qwehj

test2

nijin:qwe
nijintest2:abc

I have to change the values of nijin and nijintest2 in test1 to match that in test2, leaving all other values alone. I have tried all possible Perl replace comments without any success. Any help will be appreciated.

Edit

I have tried many open close file functions to replace the entry but none of them gives a required output. I have tried everything here In Perl, how do I change, delete, or insert a line in a file, or append to the beginning of a file? . But with no luck

Upvotes: 1

Views: 79

Answers (2)

Miller
Miller

Reputation: 35198

The following should work for importing any number of new files. I also included code for appending new entries, which you didn't specify how you wanted handled.

#!/usr/bin/env perl
use strict;
use warnings;
use autodie;

die "Usage: $0 dbfile [mapfiles ...]\n" if @ARGV < 2;

my $db = shift;

my %mapping = map {chomp; /([^:]*)/; $1 => $_} <>;

local @ARGV = $db;
local $^I = '.bak';
while (<>) {
    chomp;
    /([^:]*)/;
    print delete $mapping{$1} // $_, "\n";
}
#unlink "$db$^I"; # Uncomment if you want to delete backup

# Append new entries;
open my $fh, '>>', $db;
$fh->print($_, "\n") for values %mapping;

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753665

This works, though it could probably still be compressed:

#!/usr/bin/env perl
use strict;
use warnings;

die "Usage: $0 map [file ...]\n" unless scalar(@ARGV) >= 1;

my %mapping;
open my $fh, "<", $ARGV[0] or die "Failed to open $ARGV[0] for reading";
while (<$fh>)
{
    my($key, $value) = ($_ =~ m/^([^:]*):(.*)/);
    $mapping{$key} = "$value\n";
}
close $fh;

shift;

while (<>)
{
    my($key) = ($_ =~ m/^([^:]*):/);
    $_ = "$key:$mapping{$key}" if (defined $mapping{$key});
    print;
}

If it is called sub.pl, you can run:

perl sub.pl test2 test1
perl sub.pl test2 <test1
perl sub.pl test2 test1 test3 test4

For the first two invocations, the output is:

nijin:qwe
nijintest:qwerty
nijintest2:abc
nijin2:qwehj

Upvotes: 1

Related Questions