When dealing with this kind of task (edit/do something if consecutive lines match a certain pattern) the simplest way to do it with sed
is probably via the N;P;D
cycle aka the "sliding window":
sed -e '$!N;s/,\nPATTERN//;t' -e 'P;D' file
This gets the N
ext line into the pattern space and unconditionally attempts to s
ubstitute per the requirement. It then t
ests if the replacement was successful: if so, it branches to the end of script (no label) and autoprints the pattern space, otherwise it P
rints and D
eletes the first line from the pattern space and restarts the cycle.
Another GNU sed
method:
sed ':x /,$/{N;s/,\n]//;T x}' file
This works correctly even when the trailing comma is on an even-numbered line. Example:
printf '%s\n' 1, 2, ']' | sed ':x /,$/{N;s/,\n]//;T x}'
Output:
1,
2
How it works:
In most programming languages address labels are entirely passive -- labels mark code, but never change the action of that code. Not sed
though. In sed
jumping to a label at the beginning of a program actually changes the action of the code, or rather it avoids the implicit n
ext-line code that a sed
cycle usually starts with.
The T
est and branch if failed command T x
checks if the prior s
ubstitute command did nothing, and if so jumps to the :x
label at the beginning without either printing anything or reading a new line. Which means any odd-numbered line fetched by the append N
ext line that wasn't substituted will be re-scanned, as it should be.
For non-GNU sed
, (when the T
command isn't available and the syntax isn't as permissive), this should be more portable:
sed ':x
/,$/{
N
s/,\n]//
t
b x
}' file
,
is always at the end of the line. – agc Oct 08 '18 at 14:37