У меня есть этот текстовый файл или sdout:
text1
text2
text1
text2
text1
text2
У меня есть этот код:
perl -pe "s/text2\n\z/text3/s" text.txt #Note the modifier "/s"
Я с \ z ожидаю, что он поймет, что это последняя строка перед eof, и, следовательно, я ожидаю:
text1
text2
text1
text2
text1
text3
Но вместо этого он возвращает:
text1
text3text1
text3text1
text3 #without final newline
Что я делаю не так?
Параметр командной строки -p
означает что файл обрабатывается построчно, то есть то, что вы делаете, в основном:
while (<>) {
s/text2\n\z/text3/s;
print $_
}
Следовательно, \ z
соответствует не концу всех входных данных, а концу каждой строки.
Что вы вероятно, нужно не использовать -p
, а вместо этого прочитать полный файл и заменить только конец. Обратите внимание, что регулярное выражение можно упростить, просто используя $
, а / s
и \ z
не нужны:
perl -e 'local $/; (my $x = <>) =~s{text2$}{text3}; print $x' text.txt
Решение, которое я принял:
perl -0pe 's/text2\s*$/text3\n/' text.txt
Нет необходимости пролистывать весь файл. Используйте этот однострочник Perl:
perl -lpe 's{text2}{text3} if eof ' in_file
Печать:
text1
text2
text1
text2
text1
text3