Reputation: 353
I'm working with a markdown file in vim, and I want to number the lines. To insert the line numbers is easy:
:%s/^/\=printf('%-4d', line('.'))
But there's a hitch. I want to ignore any and all header lines (##Header) and still keep the numbers sequential. That means I can't simply insert the actual line number. Ignoring leading hashtags is no problem, but I can't figure out how to maintain an accurate count.
Upvotes: 0
Views: 403
Reputation: 58578
This might work for you (GNU nl):
nl -bp'^[^#]\|^$' file
Will line number all lines except those non-empty lines beginning with #
.
Upvotes: 0
Reputation: 196916
The following Vim command works in my limited testing:
:let i = 0 | v/^#/let i += 1 | s/^/\=i . ' '
Generalities:
|
marks the separation between two Ex commands.
g/<pattern>/<command>
executes <command>
on every line matching <pattern>
.
v/<pattern>/<command>
does the same on every line not matching <pattern>
.
When using :help :g
or :help :v
, it is important to know that everything that comes after the second /
, including |
, is part of <command>
so:
:g/foo/cmd1 | cmd2
won't do g/foo/cmd1
then cmd2
. Instead, it will do cmd1
and cmd2
on each matching line.
Specifics:
:let i = 0
initiates an iterator with value 0
,v/^#/…
will execute the remainder of the command on every line not starting with #
,let i += 1
increments the iterator,s/^/\=i . ' '
prepends the current line with the current value of the iterator followed by a space. :help \=
is used in the replacement part because it allows us to use an expression, and thus consume variables.Upvotes: 1
Reputation: 22087
It may be difficult to achieve it with vim
or sed
because they do not
have a variable
which can be modified depending on the condition.
If awk
is your option, would you please try:
awk '!/^#/ {$0 = sprintf("%-4d", ++n) $0} 1' file.md > file_new.md
An input file file.md
looks like:
# Header 1
Lorem
ipsum
dolor
### Header 2
sit
amet
Then the output file_new.md
will be:
# Header 1
1 Lorem
2 ipsum
3 dolor
### Header 2
4 sit
5 amet
!/^#/
is satisfied if the line does not start with '#'
then the following {...}
block is evaluated.$0 = sprintf("%-4d", ++n) $0
prepends a concecutive
number to the line (only if the condition above is met).1
tells awk
to print current line regardless of the condition.Upvotes: 4