Thus wrote Erik Janssen (erik.janssen@...
) on :
> Preben Guldberg wrote:
> > :g@^D \(\d\+\.\d\+ \d\d/\d\d/\d\d\) .*@
> > s//\1/
> > | +,/^COMMENTS:$/d
> > | -j
> FYI, in vm5.7 this is not going to work for multiple occurences as the
> deletion and join mess up the marking that is done beforehand, see
> manual page:
Actually it is more subtle than that - see below.
> The global commands work by first scanning through the [range] lines
> marking each line where a match occurs. In a second scan the [cmd] is
> executed for each marked line with its line number prepended. If a
> line is
> changed or deleted its mark disappears.
But none of the lines matched by :global are changed or deleted.
What I had not thought of when writing it up was that the search
pattern is changed between the first and second :subsitute command.
The way it works is
Use :g to mark all '^D delta' lines, then for each of them carry
out the sequence of commands, which goes (call the marks a...):
a 1) On first marked line, use last pattern (/^D \d.../) for :s
a 2) Deletes the next line and until /^COMMENTS:$/
a 3) Join some lines
b 1) On first marked line, use last pattern (/^COMMENTS:$) for :s
Oops, This does not match on the line matched by :global.
Thus it is necessary to repeat the :global pattern for the :substitute
> But I got it going by doing it in steps. Without your suggestions I
> would not have made it. (The input as I specified it was not completely
> correct: MR was not wrapped, version numbers are more complex and
> comments may span multiple lines, empty line below the comment always,
[--- snip ---] Thanks for the example.
If your file only contains data, you might be able to pull it off with
:global's like below (though there is no checks for comment lines that
just say 'MRs:' or 'COMMENTS:' :-)
> This is how I did it, maybe someone who was following the thread might
Hmm, a couple of comments:
> " Get the version number and the date from each line starting with D
> g@^D \(\d\+\(\.\d\+\)\+ \d\d/\d\d/\d\d\) .*$@ s//\1/
The '$' at the end of the pattern is not necessary - the '.*' pattern
is so greedy that it will match until end of line anyway.
> "Remove the MR + garbage + COMMENT
I assume that a 'MRs:' line always follows the 'D version' line.
> " Join all non-empty lines
> " Repeat it
That was up to three lines of comments. (And I can tell you don't care
about spaces at the end of lines (you may get one for empty lines)).
> " Remove remaining empty lines
> I think the g/.\+/j twice might be replaced by g/.\+/jj
If you want to go that route, the is no 'jj' command. Make it 'j|j'.
Actually, you probably want one of
1) Allow spaces at tne of line:
2) No spaces at end of line in two steps
3) No spaces at end of line in one step
:g/./,/^$/j | s/ $//
Anyway, with the first :s issue above sorted out, try
g@^D \(\d\+\(\.\d\+\)\+ \d\d/\d\d/\d\d\) @
s@^D \(\d\+\(\.\d\+\)\+ \d\d/\d\d/\d\d\) .*@\1@
| s/ $//
The :g and :s patterns need not be the same (no grouping, except for
minor versions, are necessary), but it may be easier to maintain if
they look the same (though I did strip out the .* part, it still lines
"Before you criticize someone, walk
Preben "Peppe" Guldberg __/-\__ a mile in his shoes. That way, if
(o o) he gets angry, he'll be a mile away
----------------------oOOo (_) oOOo-- - and barefoot." --Sarah Jackson