LINUX.ORG.RU

perl заменить строку в файле.

 ,


0

1

Как в perl сохранить изменения в файле? Вот фрагмент кода:

open my $fgh,'<', '/etc/locale.gen' or die $!;

while (my $line = <$fgh>) 
{	
	$line =~ s/^#\sen\wUS.UTF-8\sUTF-8/en_US.UTF-8 UTF-8/g;
	print "$line";
}
Или надо в добавок открывать другой файл на запись ('>') и записывать туда изменения? В однострочку понятно как, но как внутри сценария, сделать с наименьшими затратами на символы.


Ага.

-i: Modifies your input file in-place (making a backup of the
    original). Handy to modify files without the {copy,
    delete-original, rename} process.
anonymous ()

с наименьшими затратами на символы

Если это не однострочник, то цель совершенно неправильная. Лучше добавить три лишних строчки для понятности

annulen ★★★★★ ()
Ответ на: комментарий от annulen

да уже переписал

open(FILE, '/etc/locale.gen') or die $!;
my @array = <FILE>;
close(FILE);

my @newlines;
foreach(@array) 
{
   $_ =~ s/^#\sen\wUS.UTF-8\sUTF-8/en_US.UTF-8 UTF-8/g;
   push(@newlines,$_);
}

open(FILE, ">/etc/locale.gen") or die $!;
print FILE @newlines;
close(FILE);

Если это не однострочник, то цель совершенно неправильная

Да обычный сценарий в котором нужно выполнить это действие. Можно конечно было и на баше написать. Решил перл поизучать. Да и вот это быстрее выполняется, чем код сверху:

sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g' -i /etc/locale.gen
правда так наверно не коректно сравнивать... в целом наверно на перле быстрее.

добавить три лишних строчки для понятности

суть куска на баше

echo 'locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8' | debconf-set-selections
echo 'locales locales/default_environment_locale select en_US.UTF-8' | debconf-set-selections
sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g' -i /etc/locale.gen
dpkg-reconfigure --frontend=noninteractive locales

ving2 ()
Ответ на: комментарий от ving2

да уже переписал

1. Не используй bareword для file handle - в первой версии было правильно (open my $fgh ...)

2. Как подсказали выше, правильный алгоритм - «copy, delete-original, rename», иначе посторонний процесс, имевший несчастье открыть файл в процессе работы твоей программы, прочитает его в промежуточном состоянии

annulen ★★★★★ ()
Ответ на: комментарий от ving2

Да и вот это быстрее выполняется, чем код сверху

Еще бы, ты же записываешь строки во временный массив, а надо их сразу в выходной файл писать. Кроме того, в перловой регулярке стоят \s, а в седовой литеральные пробелы.

По-хорошему надо заэкранировать в регулярке точку, так как имеется в виду литеральная точка а не произвольный символ

Так как в данном примере идет посимвольная замена, а фичи регулярных выражений не используются (по крайней мере в sed ты обошелся без «^»), то можно заменить s на tr, будет еще шустрее

annulen ★★★★★ ()

Как правильно подсказал анонимус из первого камента. Использовать ключи -i -pe
В скрипте это может быть эквивалентно такому

BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
  #сюда s///
  s/^#\sen\wUS.UTF-8\sUTF-8/en_US.UTF-8 UTF-8/g;
}
continue {
    die "-p destination: $!\n" unless print $_;
}

pru-mike ★★ ()

Спасибо всем за советы....

ving2 ()
Ответ на: комментарий от debugger

Открой для себя CPAN

Про Path::Tiny, не видел еще, спасибо.

ving2 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.