Vim/sed/awk 查找&替换为增量整数

发布于 2024-10-14 15:51:28 字数 226 浏览 6 评论 0原文

我有一个 markdown 文件,其中包含 [this][]、[that][]、... 和 [the other][] 等单词。我知道如何在 MacVim 中找到这些单词,但是如何用 [this][1]、[that][2]、... 和 [the other][n] 替换它们,其中 n 在我的中为 26案件?

我也会接受使用 sed 或 awk 甚至 Ruby 的解决方案,如果它们被证明比使用 MacVim 更简单的话。

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

I'll also accept solutions using sed or awk or even Ruby if they prove to be simpler than using MacVim.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

戏舞 2024-10-21 15:51:28
perl -p -i -e 's/(\[.*?\])\[\]/"$1\[".(++$i)."]"/ge' /path/to/file

维姆:

:let g:lastcount=0
:function PlusPlus()
  let g:lastcount+=1
  return g:lastcount
  endfunction
:%g/./s/\V[\.\{-}][\zs\ze]/\=PlusPlus()/g
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
ζ澈沫 2024-10-21 15:51:28
ruby -p -e \
'begin t=$_.clone; $_.sub! "][]", "][#{@[email protected]_i+1}]";end until t==$_' \
  < somefile

或者,对于就地编辑文件版本:

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

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

ruby -i.tmp -p -e \
'begin t = $_.clone; $_.sub! "][]", "][#{@[email protected]_i+1}]"; end until t == $_' \
somefile
不喜欢何必死缠烂打 2024-10-21 15:51:28

嗯,在 Vim 中编写一个解决方案是完全可能的。我已经使用这个 Incrementor 对象有一段时间了:

---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

将整个代码示例复制到文件末尾的“栏”,然后保存它并获取它 (:so %) 以在 Vim 中进行测试。

Well, writing a solution to this in Vim is quite possible. I have been using this Incrementor object for a while now for these sort of things:

---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 that whole code sample right up to the 'bar' at the end in a file and then save it and source it (:so %) to test from within Vim.

红尘作伴 2024-10-21 15:51:28

如果您只需要执行一次,并且不再需要执行此操作,那么在编辑器中执行就可以了。当您必须重复执行此操作时,手动执行此操作将变得非常痛苦,这就是需要启动自动化的时候。

如果没有包含目标的文本样本,这有点像在黑暗中射击,但这似乎接近于您使用 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.

If you only have to do it once, and never again, then doing it in an editor is fine. When you have to do it repeatedly then it becomes a major pain to do it manually, and that's when automation needs to kick in.

Without a sample of the text containing the targets it is somewhat like shooting in the dark, however this seems close 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.
财迷小姐 2024-10-21 15:51:28

尝试一下:

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

Give this a try:

awk 'BEGIN{c=1}{for(w=1;w<=NF;w++){s=sub("\\[\\]","["c"]",$w);if(s)c++};print}' inputfile
不交电费瞎发啥光 2024-10-21 15:51:28

只需使用几个 vim 命令和一个宏,您就可以轻松完成此操作:

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

即搜索字符串“[]”,为第一个字符串附加数字 1。然后开始录制宏。猛拉 [] 内的所有内容,转到下一个匹配项,然后粘贴它。然后增加数字。停止录制,然后根据需要多次重播宏。它会增加每次插入的数字。

You can do this pretty easily just by using a few vim commands, and a macro:

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

That is, search for the string "[]", append the number 1 for the first one. Then start recording a macro. Yank everything inside the [], go to the next match, and paste it. Then increment the number. Stop recording and then replay the macro as many times as you need to. It will increment the number it inserts each time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文