Как заменить значения хеша во внешнем файле?

В своей программе я пытаюсь заменить значение определенного хеша во внешнем файле вновь созданным значением. Внешний файл имеет значение, отделенное табуляцией от ключа, и я прочитал хэш из внешнего файла. Я искал в Интернете, и это самый близкий способ понять, как это сделать, но, похоже, он не работает.

            open(IN, ">>$file") || die "can't read file $file";
            while (<IN>) {
            print IN s/$hash{$key}/$newvalue/;
            }
           close (IN) 

Я не совсем уверен, что мне не хватает в этой формуле.


person Community    schedule 18.12.2008    source источник
comment
Кажется немного странным называть дескриптор выходного файла IN, но что угодно... :)   -  person Keltia    schedule 19.12.2008


Ответы (4)


Tie::File может это исправить.

use Tie::File;

tie @array, 'Tie::File', $file or die "Could not tie $file: $!";

for (@array) {
    s/$hash{$key}/$newvalue/;
}
untie @array;
person Leon Timmermans    schedule 18.12.2008

http://www.sthomas.net/roberts-perl-tutorial.htm/ch13/Modifying_a_File_with___I
Google на "$INPLACE_EDIT perl"

person jbdough    schedule 07.01.2011

Вы пытаетесь читать и писать в один и тот же файл, это не сработает. Вы должны прочитать, заменить, а затем записать в другой файл. После этого вы можете заменить входной файл тем, который вы только что написали, если вам действительно нужен один файл.

person Keltia    schedule 18.12.2008
comment
Ах я вижу. Тогда есть ли способ, которым я могу просто добавить значение во внешний файл? Это все, что мне нужно, я просто ожидал, что замена сможет выполнить эту задачу. - person ; 19.12.2008
comment
Это всего лишь вариант той же задачи, поэтому вы получите тот же ответ. На самом деле это FAQ по Perl. - person Keltia; 19.12.2008

Это не будет эффективно, но должно работать, если только мой perl-fu не плох:

open(IN, "<<$file") || die "can't read file $file";
open(OUT, ">>${file}.tmp") || die "can't open file $file";
while (<IN>) {
    print OUT s/$hash{$key}/$newvalue/;
}
close(IN);
close(OUT);
exec("mv ${file}.tmp $file");

В Perl может быть команда сделать ход за вас, но я не специалист по Perl.

person FryGuy    schedule 18.12.2008
comment
Я нахожу этот подход интересным, я знаю, что вы не специалист по Perl, но если вы знаете, будет ли в новом файле все содержимое исходного файла с заменой необходимых частей? - person ; 19.12.2008
comment
Да, потому что если подстановка не происходит из-за того, что значение не найдено, то $_ не изменяется, а затем записывается в OUT - person Keltia; 19.12.2008
comment
Кстати, функция, которую вы хотите, это переименовать (СТАРЫЙ, НОВЫЙ) - person Keltia; 19.12.2008
comment
По какой-то странной причине он говорит мне, что не может прочитать файл сейчас. - person ; 19.12.2008
comment
Использовать отсоединение и переименование (переименовать старый запасной; переименовать новый старый; отвязать запасной). - person Jonathan Leffler; 19.12.2008
comment
Он по-прежнему говорит мне, что не может прочитать файл, и именно в первой строке этого фрагмента кода возникает проблема. Tie::File помогает для подстановки, но поскольку он работает с массивами, я получаю повторяющиеся значения более чем при одном запуске. - person ; 19.12.2008