Проблема здесь:
open(DES,'>>',$configfile) or die $!;
Вы открываете свой файл для добавления. Таким образом, вы получаете исходные данные, а затем ваши отредактированные данные.
Обновление: Похоже, у вас есть рабочее решение, но я подумал, что было бы интересно показать вам, как я буду напишите это.
Эта программа является фильтром Unix. То есть он читает из STDIN
и пишет в STDOUT
. Я нахожу это гораздо более гибким, чем жестко закодированные имена файлов. Вам также не нужно явно открывать файлы - это экономит время: -)
Также требуется параметр командной строки -c
, сообщающий, какой файл содержит определения для редактирования. Итак, это называется так (при условии, что мы назвали программу edit_files
:
$ edit_files -c edit_definitions.txt < your_input_file > your_output_file
И вот код.
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Std;
my %opts;
getopts('e:', \%opts);
my %edits = read_edits($opts{e});
while (<>) {
chomp;
my ($key, $val) = split /:/, $_, 2; #/ stop faulty syntax highlight
if (!exists $edits{$key}) {
print "$_\n";
next;
}
my $edit = $edits{$key};
if ($edit->[0] eq 'add') {
print "$_$edit->[1]\n";
} elsif ($edit->[0] eq 'del') {
$val =~ s/$_:// for split /:/, $edit->[1]; #/
print "$key:$val\n";
} elsif ($edit->[0] eq 'rpl') {
print "$key:$edit->[1]\n";
} else {
warn "$edit->[0] is an invalid edit type\n";
next;
}
}
sub read_edits {
my $file = shift;
open my $edit_fh, '<', $file or die $!;
my %edits;
while (<$edit_fh>) {
chomp;
# Remove comments
s/\s*#.*//; #/
my ($type, $key, $val) = split /:/, $_, 3; #/
$edits{$key} = [ $type, $val ];
}
}