Vim / Sed / AWK Найти и заменить с инкрементным целым - PullRequest
4 голосов
/ 29 января 2011

У меня есть файл уценки со словами, подобными [this] [], [that] [], ... и [other] []. Я знаю, как найти эти слова в MacVim, но как мне заменить их на [this] [1], [that] [2], ... и [other] [n], где n равно 26 в моем случай

Я также приму решения с использованием sed, awk или даже Ruby, если они окажутся проще, чем с использованием MacVim.

Ответы [ 6 ]

6 голосов
/ 30 января 2011
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
2 голосов
/ 30 января 2011

Ну, написать решение для этого в Vim вполне возможно. Я уже некоторое время использую этот объект Incrementor для таких вещей:

--- 8 <--- код VIM </p>

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

Скопируйте весь пример кода прямо в конец строки в файл, а затем сохраните его и отправьте его (:%) для тестирования из Vim.

2 голосов
/ 29 января 2011
ruby -p -e \
'begin t=$_.clone; $_.sub! "][]", "][#{@n=@n.to_i+1}]";end until t==$_' \
  < somefile

Или, для версии редактирования файла на месте:

ruby -i.tmp -p -e \
'begin t = $_.clone; $_.sub! "][]", "][#{@n=@n.to_i+1}]"; end until t == $_' \
somefile
1 голос
/ 30 января 2011

Попробуйте:

awk 'BEGIN{c=1}{for(w=1;w<=NF;w++){s=sub("\\[\\]","["c"]",$w);if(s)c++};print}' inputfile
1 голос
/ 30 января 2011

Если вам нужно сделать это только один раз, и никогда больше, тогда делать это в редакторе хорошо.Когда вам приходится делать это несколько раз, тогда становится большой боль делать это вручную, и тогда автоматизация должна начать работу.

Без образца текста, содержащего цели, это похоже на стрельбу в темноте.Однако это похоже на ваше описание с использованием 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.
0 голосов
/ 11 февраля 2011

Вы можете сделать это довольно легко, просто используя несколько команд vim и макрос:

/\[\]<cr>a1<esc>qqyi[np<C-a>q25@q

То есть найдите строку «[]», добавьте число 1 к первой,Затем начните запись макроса.Вытащите все внутри [], перейдите к следующему совпадению и вставьте его.Затем увеличьте число.Остановите запись, а затем воспроизведите макрос столько раз, сколько вам нужно.Он будет увеличивать число, которое он вставляет каждый раз.

...