Для этого нужны обратные ссылки. Просто заключите часть текста, которую хотите записать, в круглые скобки. Первый набор скобок доступен в $ 1, второй в $ 2 и так далее.
s/(\s[0-9]\s[0-9]{3})/$1I/
С Perl 5.10 мы получили именованных захватов , так что вы можете сказать
s/(?<bodytext>\s[0-9]\s[0-9]{3})/$+{bodytext}I/
Имя между <
и >
- это имя. Имена становятся ключами в переменной %+
, а значения являются захваченным текстом.
Другим решением является использование положительных просмотров нулевой ширины
s/(?<=\s[0-9]\s[0-9]{3})/I/
или его, новый для Perl 5.10, сокращение \K
s/\s[0-9]\s[0-9]{3}\K/I/
Попробуйте
perl -pi -e 's/(\s[0-9]\s[0-9][0-9][0-9])/$1I/' filename
Если вы используете двойные кавычки, $ 1 интерполируется оболочкой до того, как Perl когда-либо ее увидит. Если у вас есть проблемы с чем-то, что, по вашему мнению, должно работать, может быть, стоит взглянуть на то, что видит Perl. Вы можете сделать это с помощью B :: Deparse :
perl -MO=Deparse -pi -e "s/(\s[0-9]\s[0-9][0-9][0-9])/$1I/" filename
Это даст следующий вывод.
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
s/(\s[0-9]\s[0-9][0-9][0-9])/I/;
}
continue {
print $_;
}
-e syntax OK
Отсюда видно, что $1
отсутствует. Попробуем еще раз с одинарными кавычками:
perl -MO=Deparse -pi -e 's/(\s[0-9]\s[0-9][0-9][0-9])/$1I/' filename
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
s/(\s[0-9]\s[0-9][0-9][0-9])/$1I/;
}
continue {
print $_;
}
-e syntax OK
И один раз с побегом:
perl -MO=Deparse -pi -e "s/(\s[0-9]\s[0-9][0-9][0-9])/\$1I/" filename
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
s/(\s[0-9]\s[0-9][0-9][0-9])/$1I/;
}
continue {
print $_;
}
-e syntax OK