Re-number a list when a new entry is inserted
You can always add your new entry with a x. newentry
syntax and renumber everything afterwards with something like:
awk -F . -v OFS=. '{if (NF) $1 = ++n; else n = 0; print}'
-F .
: sets the field separator to.
1-v OFS=.
: same for the output field separator (-F .
is short for-v FS=.
).{...}
: no condition so the code inside{...}
is run for each lineif (NF)
, if the number of fields is greater than 0. WithFS
being.
, that means if the current line contains at least one.
. We could also make itif (length)
to check for non-empty lines.$1 = ++n
: set the first field to an incrementedn
(initially 0, then 1, then 2...).else n = 0
: else (when NF == 0) reset n to 0.print
: print the (possibly modified) line.
1The syntax is -F <extended-regular-expression>
but when <extended-regular-expression>
is a single character, that is not taken as a regular expression (where .
means any character) but as that character instead.
Maximum overkill (and complexity! and bugs!) can be had via the Text::Autoformat perl module.
% < input
1. foo
2. bar 100%
3. kittens
4. it is getting dark. there may be a grue
4. no seriously, it's getting dark
4. really, you should find a light or something.
4. are you even paying attention? helloooo
4. eat cake
5. unicorns
6. rainbows
% perl -MText::Autoformat -0777 -ple '$_=autoformat $_, { all => 1 }' < input
1. foo
2. bar 100%
3. kittens
4. it is getting dark. there may be a grue
5. no seriously, it's getting dark
6. really, you should find a light or something.
7. are you even paying attention? helloooo
8. eat cake
9. unicorns
10. rainbows
%
Actual results will depend on the input, desired output, options passed, etc.
VIM solutions
There's two solutions: one is via automating Ctrla keypress over a selection, second is via executing a pattern replacement with submatch(0)+1
over the selection. First the key automation.
Start by creating your list:
1. foo
2. bar 100%
3. kittens
4. eat cake
5. unicorns
6. rainbows
Insert an entry
1. foo
2. bar 100%
3. kittens
4. eat cake
4. sunshine
5. unicorns
6. rainbows
Position your cursor onto 4. sunshine
and from command mode press shift + v, then shift + g . This is visual selection till the end of file. You can also move the cursor to the end of a block in the usual ways.
Press :
to enter command mode, and you will see this: :'<,'>
. Now type in the following:
norm
Ctrl+V Ctrl+A
What Ctrl-v and ctrl-A do, is they allow you to enter "exact" key, so it will change into ^A
, highlighted. This is basically saying for all lines selected, execute in normal mode keypress Ctrl-A
, and Ctrl-A by default increments the number under cursor. You will see the numbers change
Solution in action:
Before
After
Another way would be to select everything from the first repeated number like before( Shiftv, then G ), and go into command mode to execute:
:'<,'>s/\v(^\d+)\./\=(submatch(0)+1).'.'/