“tr”命令在Vim中的等效操作是什么?

8

有这样一行代码:

xxAyayyBwedCdweDmdwCkDwedBAwe
;;;; cleaner example
__A__B__C__D__C_D_BA_

想要将ABCD替换为PQRT,例如得到

__P__Q__R__T__R_T_QP_

例如下一个bash或perl的等效物 `tr`
tr '[ABCD]' '[PQRT]' <<<"$string"

如何在“vim”中实现这个功能?(VIM - Vi IMproved 7.4(2013年8月10日,编译于2014年5月9日12:12:40))


8
这算作弊吗? %!tr 'ABCD' 'PQRT' - Kent
@Kent 呵呵...调用shell?它可以工作,但有时会遇到元字符转义的问题,特别是当想要将[]转换为()等时... - kobame
2
调用 !tr 只是为了一个短命令。tr() 更好,特别是当 (external)tr 不可用时。但是,使用 !tr() 或 [] 不会成为问题。这不是正则表达式。 - Kent
1个回答

10
你可以使用:globaltr()函数结合使用。
:g/./call setline(line('.'), tr(getline('.'), 'ABCD', 'PQRS'))

将其适应为:%Tr#ABCD#PQRS命令很容易。

:command! -nargs=1 -range=1 Translate <line1>,<line2>call s:Translate(<f-args>)

function! s:Translate(repl_arg) range abort
  let sep = a:repl_arg[0]
  let fields = split(a:repl_arg, sep)
  " build the action to execute
  let cmd = a:firstline . ',' . a:lastline . 'g'.sep.'.'.sep
        \. 'call setline(".", tr(getline("."), '.string(fields[0]).','.string(fields[1]).'))'
  " echom cmd
  " and run it
  exe cmd
endfunction

1
不错。你不需要 :g/./,因为 :call 本身可以接受范围: - Ingo Karkat
8
Vimgolf: %s/.*/\=tr(submatch(0), 'ABCD', 'PQRS')这段代码是Vim编辑器中的命令。它的作用是将当前行中所有的'A'替换为'P',所有的'B'替换为'Q',所有的'C'替换为'R',所有的'D'替换为'S'。 - Peter Rincker
2
高尔菲耶(假设光标在第一列):C<C-r>=tr(@", 'ABCD', 'PQRS')<CR><Esc> - Jordan Running
1
@Jordan。我会说“不同”。你的解决方案只适用于当前行。Peter和我的解决方案适用于任意数量的行。它们甚至保留了@"不变 - 这是插件中我欣赏的东西。顺便说一下,为了缓解第一列的限制,您可以使用S而不是C - Luc Hermitte
1
@LucHermitte 所有敏锐的观察。Vim高尔夫往往范围狭窄(例如,很少需要给出一系列行的能力),并且对于寄存器污染方面比较宽松,我的评论是以这种精神写的。干杯! - Jordan Running
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接