我可以在Vim中转置文件吗?

时间:2021-04-07 19:19:19

I know I can use AWK but I am on a Windows box. I am making a function for others that may not have AWK. I also know I can write a C program but I would love not have to create maintain and compile something for a little Vim utility I am making.

我知道我可以使用AWK,但我在Windows机器上。我正在为可能没有AWK的其他人提供功能。我也知道我可以写一个C程序,但我不想为我正在制作的一个小Vim实用程序创建维护和编译。

The original file might be

原始文件可能是

THE DAY WAS LONG 
THE WAY WAS FAST

and it would become

它会成为

TT
HH
EE

DW
AA
YY

WW
AA
SS

LF
OA
NS
GT

UPDATE: Golf rules apply to selecting correct answer.

更新:高尔夫规则适用于选择正确的答案。

UPDATE: Python fans should check out Mr. Duffy's answer below.

更新:Python粉丝应该看看Duffy先生的答案如下。

6 个解决方案

#1


Here is a command in Vim language. So you don't have to compile Vim with +python support.

这是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()

Put this in newly created .vim file inside vim/plugin dir or put this to your [._]vimrc.
Execute :TransposeBuffer to transpose current buffer

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

#2


Vim support for a number of scripting languages built in -- see the Python interface as an example.

Vim支持内置的许多脚本语言 - 以Python接口为例。

Just modify vim.current.buffer appropriately and you're set.

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

To be a little more specific:

更具体一点:

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

#3


If scripts don't do it for you, you could record the actions to a register (the carriage returns are added for readability):

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

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

This will give you a macro that you could run against the example above, or any 2-line strings of the same length. You only need to know the length of the string so you can iterate the operation the correct number of time

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

16@a

A fairly basic solution, but it works.

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

#4


The following function performs required editing operations to "transpose" the contents of the current buffer.

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

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

Below is its one-line version,

以下是它的单行版本,

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'

#5


Charles Duffy's code could be shortened/improved using izip_longest instead of izip:

使用izip_longest而不是izip可以缩短/改进Charles Duffy的代码:

function! Rotate()
    :py import vim, itertools
    :py vim.current.buffer[:] = [''.join(c) for c in itertools.izip_longest(*vim.current.buffer, fillvalue=" ")]
endfunction

#6


I've developed a vim plugin to do it. You can find it here. Run :Transpose to transpose the whole file.

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

#1


Here is a command in Vim language. So you don't have to compile Vim with +python support.

这是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()

Put this in newly created .vim file inside vim/plugin dir or put this to your [._]vimrc.
Execute :TransposeBuffer to transpose current buffer

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

#2


Vim support for a number of scripting languages built in -- see the Python interface as an example.

Vim支持内置的许多脚本语言 - 以Python接口为例。

Just modify vim.current.buffer appropriately and you're set.

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

To be a little more specific:

更具体一点:

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

#3


If scripts don't do it for you, you could record the actions to a register (the carriage returns are added for readability):

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

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

This will give you a macro that you could run against the example above, or any 2-line strings of the same length. You only need to know the length of the string so you can iterate the operation the correct number of time

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

16@a

A fairly basic solution, but it works.

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

#4


The following function performs required editing operations to "transpose" the contents of the current buffer.

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

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

Below is its one-line version,

以下是它的单行版本,

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'

#5


Charles Duffy's code could be shortened/improved using izip_longest instead of izip:

使用izip_longest而不是izip可以缩短/改进Charles Duffy的代码:

function! Rotate()
    :py import vim, itertools
    :py vim.current.buffer[:] = [''.join(c) for c in itertools.izip_longest(*vim.current.buffer, fillvalue=" ")]
endfunction

#6


I've developed a vim plugin to do it. You can find it here. Run :Transpose to transpose the whole file.

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