Общая идея: читать входные данные в виде блоков, разделенных \nval2=
. Печатайте каждый блок как есть, кроме последнего, где мы меняем текст до первого символа новой строки. Вот относительно простое решение gawk, которое обрабатывает большинство случаев:
gawk -v 'RS=\nval2=' -v ORS= \
'RT {print $0 RT} !RT {sub(/[^\n]*/, "yes"); print $0}'
Это предполагает, что первая строка не начинается с val2=
и что есть хотя бы одно совпадение. Исправление обоих дефектов значительно усложняет скрипт:
gawk -v 'RS=\nval2=' -v ORS= \
'!RT {if (NR==1) sub(/^val2=[^\n]*/, "val2=yes"); else sub(/[^\n]*/, "yes")}
{print $0 RT}'
Вот решение Perl, основанное на том же общем принципе, но читающем весь файл сразу. Я нахожу это более ясным, потому что это не должно обращаться со специальными случаями (кроме пустого файла).
perl -e 'undef $/;
@chunks = split /(?=^val2=)/m, <>;
$chunks[@chunks-1] =~ s/(?<=^val2=).*/yes/ if @chunks;
print @chunks'
С помощью расширенных регулярных выражений Perl мы можем использовать одну подстановку регулярных выражений. Просто сопоставьте ^val2=
, за которым не следует другой ^val2=
:
perl -e 'undef $/; $_=<>; s/^val2=.*\n(?!.*\nval2=)/val2=yes\n/m; print'
Я попытался воспользоваться преимуществами rsplit
Python, который может отделить последние N полей, но сдался, когда не смог заставить его работать, не будучи намного более загадочным, чем мои Perl-решения.