如何在可视模式下将文本块保存到Vim中的文件?


75

标题非常具有描述性。以防万一,我举一个例子:

START BLOCK1
something
END BLOCK1

START BLOCK2
something
somenthing...
END BLOCK2
  1. 我选择BLOCK1视觉模式
  2. 我按一下 y
  3. 我如何将被拉的BLOCK1文件保存到其他文件?

Answers:


133

选择要保存的文本,以线条图或块图模式显示,然后

:w new.txt

那是您输入的内容,但实际上您看不到上面的内容。当您按时:,您将转到命令行,该命令行将自动填充选择信息。它看起来像这样:

:'<,'>

只需输入其余的(w new.txt)即可

:'<,'>w new.txt

...然后按Enter。


18
这不提供预期的结果,因为它只写整行,而忽略了行内选择的开始和结束位置。有什么解决办法吗?否则,我想再次提出主要问题。
dronus 2012年

2
@dronus-我不太了解您的要求。据我所知,这是OP所要求的。
Rook 2012年

6
如果在任何非在线视觉模式下进行选择,则:w仍会写出所选范围所触及的全行,但不会写出行内开始或结束的确切范围。例如,如果在块选择模式下选择窄列,或者在可视选择模式下选择一行的一部分:w,则即使y复制正确的部分,整行也将由写入。
dronus 2012年

1
@dronus-啊,好了。对,那是正确的。但是,尽管我不能与他人交谈,但这样做对我来说是预期的行为。
Rook 2012年

17

选中该块后,您可以:'<,'>w other-file将仅将选定的块写入other-file:在视觉模式下击打应该'<,'>已经存在于您的命令行中,因此您实际上只需要输入即可:w other-file


3
Vim总是选择整行以管道连接到外部命令,因此您可以使用unix / cygwin'cut'命令选择选择中每行的N到M列的矩形:'<,'>w !cut -cN-M > new.txt。投票结果最高的答案感到惊讶,读者似乎不理解这个问题。
mosh

7

可能有一种更简单的方法来执行此操作,但是我要做的是创建一个新的缓冲区(或选项卡),然后将其粘贴到中p。您可以使用创建新的缓冲区,也可以使用创建:new新的标签:tabnew。您可以使用正常将缓冲区/标签写入文件:w filename


2
确保删除顶部的多余行!!(粘贴到空缓冲区中会在顶部或如果使用P底部创建多余的一行。)
lmat-恢复Monica 2012年

3

就像注释中提到的@dronus一样,:w !pbcopy建议无法正确复制,因为它复制了整行。如果我只想复制一行中的URL,将无法复制。这是可以添加到.vimrc文件中的行,以便每次您按CTRL-C时,vim中选定的行将被复制到剪贴板:

map <C-c> y:e ~/clipsongzboard<CR>P:w !pbcopy<CR><CR>:bdelete!<CR>

如果您想阅读有关此操作的详细信息,可以在我的博客上阅读此内容。

它的实现与@rmeador建议的实现相同。


2

与@songz的解决方案类似,我更喜欢使用“:new”这样

vmap <C-c> y:new ~/.vimbuf<CR>VGp:x<CR>:!pbcopy < ~/.vimbuf<CR><CR>

据我所知,pbcopy仅存在于OSX上。Linux和其他系统上有类似的程序,但是它们的名称不同且工作方式也不同。
Josh Rumbut 2015年

是的,它只有在pbcopy可执行文件时才有效:)所以一点都没有害处
chenkaie

0

基于@chenkaie的变体,对我来说效果很好:

let mapleader = "," let g:mapleader = "," vmap <leader>y y:new ~/.vbuf<CR>VGp:x<CR> nmap <leader>p :r ~/.vbuf<CR>


0

Vim获得视觉选择并保存到文件中:

function! Get_visual_selection()
    #Get the position of left start visual selection
    let [line_start, column_start] = getpos("'<")[1:2]
    #Get the position of right end visual selection
    let [line_end, column_end] = getpos("'>")[1:2]
    #gotta catch them all.
    let lines = getline(line_start, line_end)
    if len(lines) == 0
        return ''
    endif
    #edge cases and cleanup.
    let lines[-1] = lines[-1][: column_end - 2]
    let lines[0] = lines[0][column_start - 1:]
    return join(lines, "\n")
endfunction

function Save_visually_selected_text_to_file()
    let selected_text = Get_visual_selection()
    call writefile(split(selected_text, "\n"), "/tmp/something.txt")
endfunction

#the c-u does a union of all lines in visual selection.
#this goes in the vimrc
vnoremap <F10> :<c-u>call Save_visually_selected_text_to_file()<cr>

0

除了上面选择的答案之外,

  • 当使用鼠标选择(1)时,

  • 以及只想部分复制行(2)时仅复制@dronus注释中提到的整行的问题:

(1)在基于Debian的DietPi(Raspberry PI)系统上,当在我的Ubuntu 16.04工作站上使用鼠标进入并选择“ VISUAL MODE”时,vim的行为与上述首选解决方案有些不同。然后

  • y拉动它

但是如果我输入':'作为命令,它将不会显示

'<,'>

在这里我可以简单地添加我的

w new.txt

之后。因此,我自己输入了它,它确实起作用了:

'<,'>w new.txt

并将整行提取的内容复制到我的文件“ new.txt”中,而“ <”似乎意味着“复制选定的行,然后将“>”重定向到写入命令的引用文件。

(2)对于不粘贴部分行的问题(如提到的@dronus注释中的问题),解决方案(所选的一个,第一个替代方案)对我有效:

编辑第一个文件,拉动所需的文本。然后从vi(:e / path / to / other / file)中打开第二个文件并粘贴(通过键入p)。保存它(如“:w new.txt”上方。

然后,它将只复制用鼠标或“ y”标记的行的一部分。

[编辑]在我的Ubuntu系统上:有时用鼠标选择不会在vim中输入'VISUAL MODE'。然后可以使用上下文菜单选择普通的复制/粘贴...我还没有找到Ubuntu将其行为从“客户端行为”更改为“主机”的原因(withUbuntu将ssh bash窗口托管到我的“客户')...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.