1

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

Community
  • 1
  • 1
Nijin
  • 41
  • 1
  • 4
  • Where are the scripts you have tried? Have you heard of `comm`? – squiguy Mar 24 '14 at 00:08
  • @squiguy: I haven't heard of `comm`. Do you have a reference? – Borodin Mar 24 '14 at 00:11
  • @Borodin [Here](http://linux.die.net/man/1/comm) it is. But after reading it further, doesn't look like it works in this case. – squiguy Mar 24 '14 at 00:13
  • 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 http://stackoverflow.com/questions/4388304/in-perl-how-do-i-change-delete-or-insert-a-line-in-a-file-or-append-to-the-b . But with no luck – Nijin Mar 24 '14 at 00:15
  • @user183393: I appreciate your efforts, but you should edit your own question to provide additional information. Please don't add comments – Borodin Mar 24 '14 at 00:17
  • Please show your nearest-to-successful attempt. At the least, it will show us what your planned algorithm is. It isn't very hard to do, but it does require a little thinking. – Jonathan Leffler Mar 24 '14 at 01:07

2 Answers2

1

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
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0

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;
Miller
  • 34,962
  • 4
  • 39
  • 60