Reputation: 301
I have a text file with a list in it:
dateformatfile.ext
dateformatfile.ext
dateformatfile.ext
...
I need to add a padded number to the end of each, like so:
dateformatfile.ext 00001
dateformatfile.ext 00002
dateformatfile.ext 00003
...
There are a lot, so I need to have a command to do this somehow.
Thanks in advance.
Upvotes: 3
Views: 4687
Reputation: 361
If you have PERL in your environment, you can run a PERL one-liner inside your VIM session.
:%! perl -pe " $count++ ; s/$/$count/"
The caveat is that you might have to use double quotes around your perl script. On my PC, PERL will run if I use single quotes. But I cannot address variables with the dollar sign.
Upvotes: 0
Reputation: 6250
Here is my take.
Position cursor on first line where you want to add the first number.
:let i=0
Define a variable to hold the count.
qm
Start to record a macro into register m.
A <C-R>=printf("%05d", i)<CR><ESC>
Add a space and the ouput from printf.
:let i+=1
Increment the count for the next macro execution.
q
End the recording of the macro.
jVG
Visual select the rest of the document where we want to add numbers.
:normal @m
Execute the macro to add the numbers to the selected lines.
I think this approach has some advantages:
:g/ext$/ normal @m
Execute macro stored in register m on lines ending in ext.
Upvotes: 4
Reputation: 195209
if your text block is sitting at the beginning of the file. which means the line you want to append "00001" is the first line of your file, try this command, I just simply check the line ending with ext
, you could change it to right regex if it is needed:
:%s/ext$/\="ext ".printf("%05d", line("."))/g
if the text block is not at the beginning of the file. You just check the first line (the line you want to append 00001) of the block and get the line number, for example, line number 5:
:let b=5|%s/ext$/\="ext ".printf("%05d", line(".")-b+1)/g
Upvotes: 2
Reputation: 2599
I would do this using macros (I like macros :D).
First, let's take care of the numbers (we'll pad them later). Add manually the number 1 at the end of the first line. Then record this macro on the first line :
qq - record the macro q
$ - go at the end of the line
F<space> - go backward to the last space
"ay$ - copy till the end of the line in the buffer a
j$ - go at the end of the line below
"ap - copy the buffer content
<ctrl+A> - increment the number
q - stop recording the macro
Now you can apply it a bunch of times with 1000@q (it will stop at the end of the file).
This is not really pretty but it does the job.
For the padding, I would use another ugly trick. First, use a regex to match 3 digits numbers and add a 0 before, then do the same with 2 digits numbers (add two 0 this time) and so on...
vim macros are pretty ugly but they are useful to me when I am too tired to write a oneliner (I should learn awk though). Also, they can help you remember some obscure, yet useful vim shortcuts.
Upvotes: 0
Reputation: 34677
One could very easily do this using awk. The NR variable gives you the record number, and records map to lines unless the RS variable is redefined. So the following:
awk -e '{ print $0 NR }' filename
should do the trick. Padding them is an exercise left up to the reader.
Upvotes: 0
Reputation: 20640
Assuming you want to do this for every line in your file, you can use the line number like this:
:execute "% normal A \<C-R>=printf(\"%05d\", line(\".\"))\<CR>"
where
execute(...)
runs the string as a command% normal
runs a normal command on every line of the fileA
appends to the line<C-R>=
inserts the result of a commandprintf("%05d", ...)
formats the second parameters as a five-digit numberline(".")
gets the number of the current line<CR>
completes the <C-R>=
insertionUpvotes: 11