I tested your script with GNU sed
and it produced the expected result. However, this is not portable to other sed
versions, as you use \n
inside []
and in the replacement, which is undefined by the standard.
Using it in the replacement can easily be avoided:
sed -e '1h;2,$H;$!d;g' -e 's/\(macroa{\([a-z]*\) [^\n]*\)\(\nmacrob{\)\2 /\1\3/g'
To use it in the []
expression can be done with a trick -- you use the y
command to exchange the newline with a normal character before the replacement and change it back afterwards; in this case I use |
:
sed -e '1h;2,$H;$!d;g' -e 'y/\n|/|\n/;s/\(macroa{\([a-z]*\) [^|]*\)\(|macrob{\)\2 /\1\3/g;y/\n|/|\n/'
This is the universal solution, however I think it's ugly. In most cases, instead of [^\n]
, you can write [[:print:]]
, because typically all code except for the newlines consists of printable characters, so it's:
sed 'H;1h;$!d;g;s/\(macroa{\([a-z]*\) [[:print:]]*\)\n\(macrob{\)\2 /\1\n\3/g'
(I also simplified your initial 1h;2,$H
to H;1h
.)
Considering don_crissti's comment, I add that the typical approach to solve this kind of Problem is the N;P;D
cycle: Always add the N
ext line, process both together, P
rint the first line and D
elete it from the pattern space to continue with the second:
sed 'N;s/\(macroa{\)\([a-z]* \)\(.*\nmacrob{\)\2/\1\2\3/;P;D'
sed
, this should work. What result are you actually getting? – Kusalananda Feb 20 '18 at 06:40abc
? This would get converted to spaces when pasting it to your question here. – Philippos Feb 20 '18 at 07:22