14

我知道我可以使用 Awk,但我在 Windows 机器上,并且我正在为可能没有 Awk 的其他人创建一个函数。我也知道我可以编写一个 C 程序,但我不希望为我正在制作的一个小 Vim 实用程序提供需要编译和维护的东西。

原始文件可能是:

THE DAY WAS LONG 
THE WAY WAS FAST

在转置之后,它应该变成:

TT
HH
EE

DW
AA
YY

WW
AA
SS

LF
OA
NS
GT

更新

4

6 回答 6

12

这是 Vim 语言的命令。所以你不必编译带有 +python 支持的 Vim。

function! s:transpose()
    let maxcol = 0
    let lines = getline(1, line('$'))

    for line in lines
        let len = len(line)
        if len > maxcol 
            let maxcol = len
        endif
    endfor

    let newlines = []
    for col in range(0, maxcol - 1)
        let newline = ''
        for line in lines
            let line_with_extra_spaces = printf('%-'.maxcol.'s', line)
            let newline .= line_with_extra_spaces[col]
        endfor
        call add(newlines, newline)
    endfor

    1,$"_d
    call setline(1, newlines)
endfunction

command! TransposeBuffer call s:transpose()

把它放在 vim/plugin 目录中新创建的 .vim 文件中,或者把它放到你的 [._]vimrc 中。
执行:TransposeBuffer转置当前缓冲区

于 2009-04-01T09:42:24.583 回答
10

Vim 支持多种内置脚本语言——以 Python 接口为例。

只需vim.current.buffer适当修改即可。

更具体一点:

function! Rotate()
python <<EOF
import vim, itertools
max_len = max((len(n) for n in vim.current.buffer))

vim.current.buffer[:] = [
    ''.join(n) for n in itertools.izip(
        *( n + ' ' * (max_len - len(n))
           for n in vim.current.buffer))]
EOF
endfunction
于 2009-04-01T05:13:33.073 回答
5

如果脚本不为您执行此操作,您可以将操作记录到寄存器中(添加回车是为了便于阅读):

qa
1G0
xGo<Esc>p
1G0j
xGp
q

这将为您提供一个可以针对上述示例运行的宏,或任何相同长度的 2 行字符串。您只需要知道字符串的长度,就可以将操作迭代正确的次数

16@a

一个相当基本的解决方案,但它有效。

于 2009-04-01T10:01:20.153 回答
1

以下函数执行所需的编辑操作以“转置”当前缓冲区的内容,而不管其中的行数。

fu!T()
let[m,n,@s]=[0,line('$'),"lDG:pu\r``j@s"]
g/^/let m=max([m,col('$')])
exe'%norm!'.m."A \e".m.'|D'
sil1norm!@s
exe'%norm!'.n.'gJ'
endf

为了“打高尔夫球”,这里是它的单行版本:

let[m,n,@s]=[0,line('$'),"lDG:pu\r``j@s"]|exe'g/^/let m=max([m,col("$")])'|exe'%norm!'.m."A \e".m.'|D'|exe'sil1norm!@s'|exe'%norm!'.n.'gJ'
于 2011-09-06T13:23:13.030 回答
0

查尔斯达菲的代码可以缩短/改进使用izip_longest而不是izip

function! Rotate()
    :py import vim, itertools
    :py vim.current.buffer[:] = [''.join(c) for c in itertools.izip_longest(*vim.current.buffer, fillvalue=" ")]
endfunction
于 2011-09-06T09:58:16.900 回答
0

我开发了一个 vim 插件来做到这一点。你可以在这里找到它。运行:Transpose转置整个文件。

于 2012-05-06T12:18:38.533 回答