Reputation: 41
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
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
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