Vim / sed / awk Find and replace with incremental integer

I have a markdown file with words like [this] [], [that] [], ... and [other] []. I know how to find these words in MacVim, but how to replace them with [this] [1], [that] [2], ... and [other] [n], where n is 26 in my case?

I will also make decisions using sed or awk or even Ruby if they are easier than using MacVim.

+4
source share
6 answers
perl -p -i -e 's/(\[.*?\])\[\]/"$1\[".(++$i)."]"/ge' /path/to/file 

Vim:

 :let g:lastcount=0 :function PlusPlus() let g:lastcount+=1 return g:lastcount endfunction :%g/./s/\V[\.\{-}][\zs\ze]/\=PlusPlus()/g 
+6
source
 ruby -p -e \ 'begin t=$_.clone; $_.sub! "][]", "][#{@ n=@n.to _i+1}]";end until t==$_' \ < somefile 

Or, for the edit-the-file-in-place version:

 ruby -i.tmp -p -e \ 'begin t = $_.clone; $_.sub! "][]", "][#{@ n=@n.to _i+1}]"; end until t == $_' \ somefile 
+2
source

Well, writing a solution for this in Vim is quite possible. I used this Incrementor object for a while for things like this:

--- 8 <--- vim code

 function! Incrementor(start, step) let incrementor = {} let incrementor.initial_value = a:start let incrementor.value = incrementor.initial_value let incrementor.step = a:step function incrementor.val() dict return self.value endfunction function incrementor.next() dict let self.value += self.step return self.value endfunction function incrementor.reset() dict let self.value = self.initial_value return self.value endfunction return incrementor endfunction " With the Incrementor function above saved in, say, " ~/.vim/plugin/incrementor.vim, you can then create incrementors as you need " them and use them in substitutions, like this: let inc = Incrementor(0,1) 28,$s/\v\[(\w+)\]\[\]/\="[".submatch(1)."][".inc.next()."]"/ finish " test case foo [this][] [that][] [theother][] bar 

Copy this sample of all the code right to "bar" at the end of the file, and then save it and send it (: so%) for verification from Vim.

+2
source

If you need to do this only once and never again, then do it in the editor in order. When you have to do this multiple times, it becomes a big pain to do it manually, and that when automation is required.

Without sample text containing targets, this is similar to shooting in the dark, however this is similar to your description using Ruby:

 text = %{ [Lorem][] ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore [et][] dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi [ut][] aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse [cillum][] dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui [officia deserunt][] mollit anim id est laborum. } text.scan(/\[[^\]]+\]\[\]/).each_with_index{ |t, i| text[t] = t.sub('[]', "[#{1 + i}]") } puts text # >> # >> [Lorem][1] ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut # >> labore [et][2] dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco # >> laboris nisi [ut][3] aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in # >> voluptate velit esse [cillum][4] dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat # >> non proident, sunt in culpa qui [officia deserunt][5] mollit anim id est laborum. 
+1
source

Try:

 awk 'BEGIN{c=1}{for(w=1;w<=NF;w++){s=sub("\\[\\]","["c"]",$w);if(s)c++};print}' inputfile 
+1
source

You can do this quite easily by simply using a few vim commands and a macro:

 /\[\]<cr>a1<esc>qqyi[np<Ca> q25@q 

That is, find the line "[]", add the number 1 for the first. Then start recording the macro. Yankees are all inside [], go to the next match and insert it. Then increase the number. Stop recording, and then repeat the macro as many times as you need. It will increment the number that it inserts each time.

0
source

Source: https://habr.com/ru/post/1337610/


All Articles