You could use something like this in awk:
awk '/X/ || f == 1 && sub(/Y,/, "B,") { ++f } 1' file
This sets the flag f
to 1 (or true) when the pattern /X/
is matched. When f
is true and sub
returns a true value (which it does when it performs a substitution), then s
is set to true and f
back to false. This means that f
is only true once, so only one occurrence of Y,
will be substituted.
Testing it out on a slightly different example to the one you showed in your question:
$ cat file
Y,
A,
X,
C,
D,
Y,
A,
X,
Y,
$ awk '/X/ && !s { f = 1 } f && sub(/Y,/, "B,") { s = 1; f = 0 } 1' file
Y,
A,
X,
C,
D,
B,
A,
X,
Y,
As you can see, only the Y,
after the first X
has been replaced. It doesn't matter how many lines there are between the X
and the Y,
, or if there are more than one X
before the first Y,
.
If you want to substitute all occurrences of Y,
after X
appears, then you can simplify the code:
awk '/X/ { f = 1 } f { sub(/Y,/, "B,") } 1' file
As before, this sets the flag f
when /X/
has been found. It then performs the substitution every time Y,
is found from that point onward.
Testing it out, using the same input as above:
$ awk '/X/ && !s { f = 1 } f { sub(/Y,/, "B,") } 1' file
Y,
A,
X,
C,
D,
B,
A,
X,
B,