still I'm thinking the exact syntax of this is kind of hard to understand...for my uneducated eyes at least...

:g#classifier-group\>.*\n\s*[1-9]\d* packets, [1-9]\d* bytes#.,+1p

//this means we are "extracting" the matched lines only, means what ever we'll do next based on this, we'll ignore those un-matched lines, it seems not the case...
:g#classifier-group\>.*\n\s*[1-9]\d* packets, [1-9]\d* bytes#

//this is very tricky part for me
.,+1p

"." is "current line", for me this clearly should mean the "current matched line", which is actually 2 real lines here since we are running the multi-line regex. but obviously in this context, the "." was used to describe "only the 1st line out of all matched lines", right?

and that "+1":
the "1st matched line" plus "1 more" line, but shouldn't that offset also be used from within the pool of matched lines? or regardless of match or not?
my test shows if you put +2 it will print non-matched lines too:

:g/classifier-group.*\n.*[1-9]\d* packets, [1-9]\d* bytes/.,+2p
 41     classifier-group dhcp entry 1
 42       313 packets, 118332 bytes
 43       rate-limit-profile dhcplimit        <--non-matched line
369     classifier-group jnpr-VIDEO-TRAFFIC entry 41
370       58658 packets, 8889186 bytes
371       rate-limit-profile video-upstream   <--non-matched line

so the right logic here looks is:

:g/.../ find some matched line(S),
no matter how many lines got matched, take only 1st line, trash all others
use that as the start of the range
use another offset (here +1) based on original text (not matched lines), as end of range
print


Then what if I want:
the line containing classifier-group
followed by a line x packets, y bytes
followed by a line rate-limit-profile
but I only want 1st & 3rd line under these constraint, since only these are interested lines?

(so following patterns will be ignored)
      classifier-group dhcp entry 1
        rate-limit-profile dhcplimit
)


regards
ping



ok now the tricky part:


On 6/14/12 11:38 PM, ping wrote:
hi Ben:
thanks for the answer and explanation.

sorry about the html email - I didn't notice that and I think I just set
it up to text emails only. Please do let me know if there is still an
issue.

yes the answer you provided is exactly what I'm looking for, great to
learn and appreciate the explanation. Now I also understand Christian'
suggestion better :)

this
[range-start via :g],[range-end via line offset]p
method is cool...

now I'm thinking one step further :)
is there a more "scalable" method?
in my given example I only need "2 continuous lines", what if I actually
don't know (or don't want to count) how many lines it will match and I
simply just need to print them all (from the 1st to the end of matched
lines)?

///this doesn't work
:g#classifier-group\>.*\n\s*[1-9]\d* packets, [1-9]\d* bytes#.,line('$')p

E492: Not an editor command: ,line('$')p



here per the :help line() it looks line('$') might be the "last line"
that I need here as a range:

line({expr}) The result is a Number, which is the line number of the file
position given with {expr}. The accepted positions are:
. the cursor position
$ the last line in the current buffer
'x position of mark x (if the mark is not set, 0 is
returned)
w0 first line visible in current window
w$ last line visible in current window
v In Visual mode: the start of the Visual area (the
cursor is the end). When not in Visual mode
returns the cursor position. Differs from '< in
that it's updated right away.
Note that a mark in another file can be used. The line number
then applies to another buffer.
To get the column number use col(). To get both use
getpos().
Examples: >
line(".") line number of the cursor
line("'t") line number of mark t
line("'" . marker) line number of mark marker





On 6/14/12 10:39 PM, Ben Fritz wrote:
On Thursday, June 14, 2012 4:17:55 PM UTC-5, ping wrote:

to be more precise , I want to extract only those adjacent lines
like following,



<font size="+1"><font face="monospace"> classifier-group
jnpr-VIDEO-TRAFFIC entry 2

0 packets, 0 bytes</font></font>


Thank you for finally being precise.

Now we can answer your question.

First, is there any way you can stop using the obnoxiously formatted HTML
emails? The list convention is plaintext, and the large font size is
especially jarring.

Anyway...you learned that a :g command only runs a command on the
first line
of a match, if you specify a multi-line pattern. But, you want to specify
which lines to act on based on a multi-line match; i.e., a line with
"classifier-group" followed by a line with "X packets, Y bytes" where
X and
Y are both non-zero numbers. So you will need to use a multi-line
regex, and
also the trick shown by others in this thread, to specify a range for the
command which :g runs on each matching first line, so that you can print
multiple lines starting at each first line of your multi-line regex.

I think, this should do what you want:

:g#classifier-group\>.*\n\s*[1-9]\d* packets, [1-9]\d* bytes#.,+1p

Note carefully what this does: it matches a multi-line pattern of exactly
two lines with the characteristics you describe, and runs the "print"
command on the first line that matches, plus the next line (thus, both
matched lines).


--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Reply via email to