General idea: read the input in chunks separated by \nval2=
. Print every chunk as is, except for the last chunk where we change the text up to the first newline. Here's a relatively simple gawk solution that handles most cases:
gawk -v 'RS=\nval2=' -v ORS= \
'RT {print $0 RT} !RT {sub(/[^\n]*/, "yes"); print $0}'
This assumes that the first line doesn't start with val2=
and that there is at least one match. Fixing both defects complicates the script significantly:
gawk -v 'RS=\nval2=' -v ORS= \
'!RT {if (NR==1) sub(/^val2=[^\n]*/, "val2=yes"); else sub(/[^\n]*/, "yes")}
{print $0 RT}'
Here's a Perl solution based on the same general principle, but reading the whole file at once. I find it clearer because it doesn't have to handle special cases (other than the empty file).
perl -e 'undef $/;
@chunks = split /(?=^val2=)/m, <>;
$chunks[@chunks-1] =~ s/(?<=^val2=).*/yes/ if @chunks;
print @chunks'
With Perl's extended regexps, we can use a single regexp substitution. Just match the ^val2=
that's not followed by another ^val2=
:
perl -e 'undef $/; $_=<>; s/^val2=.*\n(?!.*\nval2=)/val2=yes\n/m; print'
I tried taking advantage of Python's rsplit
which can split off the last N fields, but gave up when I couldn't get it to work without being much more cryptic that my Perl solutions.