Re: how to search and replace some text in a .conf file
by Your Mother (Archbishop) on May 18, 2009 at 19:00 UTC
|
I have quite a bit of personal distaste for Config::General but it might be what the doctor ordered in this case. You may have to adjust and I'm not sure if there's a setting to retain =s on the serialized config.
use Config::General;
my $config = Config::General->new(-String => [ <DATA> ]);
my %data = $config->getall();
$data{be_address} = "192.168.106.55";
my $new_config = Config::General->new(\%data);
print "Original:\n", $config->save_string();
print "\nNew:\n", $new_config->save_string();
__DATA__
be_address = remote-be-address
be_port = 9000
svs_port = 8733
log = log.txt
verbose = 10
screen_print = true
fe_id = 1
encryption_key = default_encrypt
fe_id_last = 1
mtu = 45K
cpu_throt = 100
bandwidth_throt = 100
system_tray_icon_enable = true
email_notification_level = 10
web_access_enable = true
sync_enable = true
software_settings_interval = true
min_space_for_dist = 30M
| [reply] [Watch: Dir/Any] [d/l] |
Re: how to search and replace some text in a .conf file
by Corion (Patriarch) on May 18, 2009 at 17:35 UTC
|
Maybe you want to use one of the templating systems? Template Toolkit is geared for creation of arbitrary text files, for example. Otherwise, you'll have to write some code. Maybe you want to show us what code you've already written and where exactly you have problems?
| [reply] [Watch: Dir/Any] |
Re: how to search and replace some text in a .conf file
by jwkrahn (Abbot) on May 18, 2009 at 18:44 UTC
|
perl -i -pe's/^(be_address\s*=\s*).*/${1}192.168.106.55/' svs.conf
| [reply] [Watch: Dir/Any] [d/l] |
Re: how to search and replace some text in a .conf file
by Marshall (Canon) on May 18, 2009 at 21:29 UTC
|
One option is the Config::Tiny module.
Its pretty easy to use. But note that it does not preserve the order of params when you write the file back out.
#!/usr/bin/perl -w
use strict;
use Config::Tiny;
use Data::Dumper;
my $Config = Config::Tiny->read( 'configtinytest.ini' );
# "_" is the default section (the one with no name)
$Config->{'_'}->{'be_address'} = '192.168.106.55';
print Dumper ($Config);
$Config->write( 'configtinytest2.ini' );
__END__
configtinytest.ini:
-------------------
be_address = remote-be-address
be_port = 9000
svs_port = 8733
log = log.txt
verbose = 10
screen_print = true
fe_id = 1
encryption_key = default_encrypt
fe_id_last = 1
mtu = 45K
cpu_throt = 100
bandwidth_throt = 100
system_tray_icon_enable = true
email_notification_level = 10
web_access_enable = true
sync_enable = true
software_settings_interval = true
min_space_for_dist = 30M
configtinytest2.ini:
--------------
bandwidth_throt=100
be_address=192.168.106.55
be_port=9000
cpu_throt=100
email_notification_level=10
encryption_key=default_encrypt
fe_id=1
fe_id_last=1
log=log.txt
min_space_for_dist=30M
mtu=45K
screen_print=true
software_settings_interval=true
svs_port=8733
sync_enable=true
system_tray_icon_enable=true
verbose=10
web_access_enable=true
| [reply] [Watch: Dir/Any] [d/l] |
Re: how to search and replace some text in a .conf file
by morgon (Priest) on May 18, 2009 at 23:46 UTC
|
For a quick one-liner try this:
perl -i.old -pe 's|^(be_address =).*|$1 192.186.106.55|' svs.conf
In case this goes wrong, the previous version of the file is kept as svs.conf.old (that's the -i.old) - so no risk in trying. | [reply] [Watch: Dir/Any] [d/l] |
Re: how to search and replace some text in a .conf file
by bichonfrise74 (Vicar) on May 18, 2009 at 21:01 UTC
|
I think you just forgot to print the results...
while ( <IN> ) {
s/remote-be-address/192.168.106.60/g;
print;
}
| [reply] [Watch: Dir/Any] [d/l] |
Re: how to search and replace some text in a .conf file
by punch_card_don (Curate) on May 18, 2009 at 18:14 UTC
|
open inFILE, "svs.conf" or die $!;
@lines = <inFILE>;
close inFILE;
open outFILE, ">svs.conf" or die $!;
for $i (0 .. $#lines) {
($param, $value) = split(/\=/, $lines[$i]);
if ($param eq 'be_address') {
$value = $new_value;
print outFILE $param." = ".$value;
}
else {
print outFILE $lines[$i];
}
}
close outFILE;
| [reply] [Watch: Dir/Any] [d/l] |
|
Please don't suggest that people use clobbery global variables or insecure
two-arg open. Something like this is cleaner, safer, and simpler (though I
didn't test it, and it may benefit from the use of File::Copy instead
of rename):
my $newfile = "svs.conf.$$";
open my $in, '<', 'svs.conf' or die "Can't read svs.conf: $!";
open my $out, '>', $newfile or die "Can't write '$newfile': $!";
while (<$in>) {
s/\bbe_address\b =/, $new_value;
print {$out} $_;
}
close $out;
rename( 'svs.conf', $newfile );
| [reply] [Watch: Dir/Any] [d/l] |
|
$input = "svs.conf";
open IN, "+> $input" or die "Unable to open $input for writing, $!,sto
+pped";
while ( <IN> ) {
s/remote_be_address/192.168.106.60/g;
}
close IN;
Still not getting the correct result. :( | [reply] [Watch: Dir/Any] [d/l] |
|
You should also output your text somewhere. Look at print, or, if you want to do an in-place change, potentially look at Tie::File.
| [reply] [Watch: Dir/Any] |
|
There were a few things in punch_card_don that really should have been tidied up before being presented as sample code to someone new to Perl.
First off, always use strictures (use strict; use warnings; - see The strictures, according to Seuss).
Second, always use the three parameter form of open. The intent is clearer and it's not subject to the security issues that the two parameter form is prone to.
Always use lexical file handles (open my $in, '<', $input or die ...;).
And avoid slurping files. Actually that one you sorted out for yourself - well done!
Something to consider - editing a variable record length file in place doesn't work because you can't adjust the size of an individual record without rewriting all the records that follow it. A text file is generally a variable length record file type - each line is a record. About the only way around the problem is to make an edited copy of the original file, then replace the original with the new file by judicious file deletion and renaming.
True laziness is hard work
| [reply] [Watch: Dir/Any] [d/l] |
|
If I'm not mistaken, the +> operator in your OPEN opens the file for reading & writing, creating it if it doesn't yet exist, but truncating it if it already exists.
| [reply] [Watch: Dir/Any] |