#perl #splice
#perl #сращивание
Вопрос:
Я новичок в perl, и мне нужно отредактировать текстовый файл, добавив немного текста после того, как я найду ключевое слово (совпадение), мне нужно сохранить изменения в том же файле, но сохранить всю старую информацию, ничего не перезаписывать.
Ключевое слово (совпадение) и информация, которую я хочу добавить, будут оставаться неизменными каждый раз, даже если другие данные из файла изменятся.
To make a summary:
data that will change (not interested)
...
empty spaces < DATA >B506JGHD (< DATA > it would be the keyword(match) and i want to add for example 00000001 after it)
output that I need:empty spaces< DATA >00000001B506JGHD
...
empty spaces< DATA >J6443MNF
output:empty spaces< DATA >00000002J6443MNF
...
empty spaces< DATA >C89583F
output:empty spaces< DATA >00000003C89583F
...
other data (not interested)
и так далее, это было бы как 7 < ДАННЫХ > в файле, поэтому я хочу добавить 00000000 к 00000006 для каждого < ДАННЫЕ >.
Я ищу простое решение, если оно существует, я знаю, что мне, вероятно, нужно прочитать текстовый файл, найти ключевое слово и переписать все, но я не уверен, как это сделать.
What I tried so far is this:
use strict;
use warnings;
open FILE, "<FL_85E920795_Y060_H21_V001_E.odx" or die $!;
my @lines = < FILE >;
close FILE or die $!;
my $idx = 0;
my $string = '00000000';
do {
if($lines[$idx] =~ /< DATA >/)
{
splice @lines, $idx, 0, $string ;
$idx ;
}
$idx ;
} until($idx >= @lines);
open FILE, ">FL_85E920795_Y060_H21_V001_E.odx" or die $!;
print FILE join("",@lines);
close FILE;
но мне это не так помогает, поскольку мой вывод выглядит следующим образом:
00000000 пустые места < ДАННЫЕ >Информация, если я попытаюсь переместить нужные данные перед < DATA >, они перезапишут все.
Первый ответ, который сработает для меня, я приму как решение. Большое вам спасибо
Ответ №1:
#!/usr/bin/perl
use strict;
use warnings;
my $counter = "00000000";
while (<>) {
s{< DATA >K}{ $counter }eg;
print;
}
Использование:
fn=FL_85E920795_Y060_H21_V001_E.odx
the_script "$fn" >"$fn".new
mv "$fn".new "$fn"
K
«сохраняет» то, что было сопоставлено с K
, и, таким образом, заменяет только пустую строку, которая следует < DATA >
, значением, возвращаемым выражением замены.
Как «однострочник»:
perl -i -pe'BEGIN { $c = "00000000" } s{< DATA >K}{ $c }eg'
FL_85E920795_Y060_H21_V001_E.odx
Комментарии:
1. Возможно, я не правильно понял, я пытался: использовать строгий; использовать предупреждения; мой $filename = ‘FL_85E920795_Y060_H21_V001_E.odx’; открыть (FH, ‘<‘, $filename) или умереть $!; мой $counter = «00000000»; в то время как (<>) { s{< DATA > K}{ $counter },например; печать; } закрыть (FH); Но это только копирует текст снова, ничего не добавляя. Если я использую > вместо < при открытии файла, файл будет пустым, а вся информация будет перезаписана. Спасибо.
Ответ №2:
Желаемый результат может быть достигнут с помощью следующего демонстрационного кода
ПРИМЕЧАНИЕ:
- это решение считывает весь файл в память целиком
- если файл слишком большой, предпочтительным подходом было бы чтение построчно
use strict;
use warnings;
use feature 'say';
my $count = 0;
my $re_match = qr/< DATA >/;
my $data = do { local $/; <DATA> };
$data =~ s/$re_match/sprintf "d",$count /ge;
say $data;
__DATA__
To make a summary:
data that will change (not interested)
...
empty spaces < DATA >B506JGHD (< DATA > it would be the keyword(match) and i want to add for example 00000001 after it)
output that I need:empty spaces< DATA >00000001B506JGHD
...
empty spaces< DATA >J6443MNF
output:empty spaces< DATA >00000002J6443MNF
...
empty spaces< DATA >C89583F
output:empty spaces< DATA >00000003C89583F
...
other data (not interested)
Вывод
To make a summary:
data that will change (not interested)
...
empty spaces 00000000B506JGHD (00000001 it would be the keyword(match) and i want to add for example 00000001 after it)
output that I need:empty spaces0000000200000001B506JGHD
...
empty spaces00000003J6443MNF
output:empty spaces0000000400000002J6443MNF
...
empty spaces00000005C89583F
output:empty spaces0000000600000003C89583F
...
other data (not interested)
Комментарии:
1. Ikegami предлагает более элегантное решение, когда
$counter
присваивается значение00000000
, которое позволяет использовать$count
вместоsprintf "d", $cont
операции замены.2. Это удаляет
< DATA >
и добавляет завершающую пустую строку