4

I have a giant html file which is a mess (not my fault). I want to add to some nodes (about 400) a unique id. They all have are of the same class, so I can add the id like this

:% s/class="some-class"/& id=<some id>/

My problem is generating the id - its has to be unique for each match.

Any ideas?

statox
  • 49,782
  • 19
  • 148
  • 225
elyashiv
  • 2,429
  • 2
  • 18
  • 23
  • 1
    Note that this strategy may fail if any of those nodes already has an id, particularly an id supplied after the class. – KRyan Sep 24 '15 at 00:10

2 Answers2

3

Could you use the expression replacement (:help sub-replace-expression) and a simple counter function? Something like

function! MyCount()
    if exists('w:count')
        let w:count = w:counter + 1
    else 
        let w:count = 1
    endif
    return w:count
endfunc

:%s/class="some-class"/\=submatch(0) . ' "id"="' . MyCount() . '"'/
:unlet w:counter

Assuming the id attribute and value should both be enclosed in quotes.

submatch() is similar to \0 in the replacement, but plays well with in an expression replacement (see :help submatch()).

jjaderberg
  • 3,489
  • 1
  • 14
  • 19
  • 1
    That would give a invalid id, ref. Perhaps something like return printf('foo%03d', w:count) if one want to get fancy. – Runium Sep 24 '15 at 03:14
2

Based on the solution given by @jjaderberg, on Linux systems you can get a uuid with the command

uuidgen

A solution could be to use the following one liner:

%s/class="some-class"/\=submatch(0) . ' id=' . system('uuidgen')/

To get this kind of result:

class="some-class" id=db2c6d1c-4646-4998-bec8-c697e5bc668c

This clearly isn't the best solution (I think jjaderbeg's one is far better), but I think the idea to add the result of an external command in a substitution can (sometimes) be interesting .

statox
  • 49,782
  • 19
  • 148
  • 225
  • 1
    Eeek! If you're going to rely on external facilities anyway, use the uuidgen command. Simpler, part of util-linux, so highly likely to be installed anyway. – muru Sep 23 '15 at 21:04