admin 管理员组

文章数量: 887021

0. Vim的 可视模式 有三个不同的版本: character mode(按字符), line mode(按行), block mode(按区域)

  • Character mode: v (lower-case)  : 按 字符 进行选择
  • Line mode: V (upper-case)  :  按 进行选择
  • Block mode: Ctrl+v     按 m x n 列进行选择,用于操作表格类的数据,

character mode 应用

如何从一个地方移动一段话到另外一个地方?

v ->  w或 nl 或 fn ->  d  ->  ngg -> p

将鼠标放置在这段话的第一个字符,然后 v,然后选择这段话到末尾,然后d,找到另外一个地方并按p粘贴即可,其中 nl是向右移n个字符,n为一个数字。 fn是向右寻找第一个n,n可以换成其他字符,ngg是快速切换到另外一个地方。  这个命令也可以 将 d 删除 改为 y 复制,即复制一段话到一个另外的地方。

如何直接修改一个语句?

v ->  w或 nl 或 fn ->  c  ->  输入你的新语句 -> esc

将鼠标放置在这段话的第一个字符,然后 v,然后选择这段话到末尾,然后c,输入你的语句,然后esc即可,其中 nl是向右移n个字符,n为一个数字。 fn是向右寻找第一个n,n可以换成其他字符。

line mode 应用

如何从一个地方移动 几行 到另外一个地方?

这个问题和上面的问题很同质,只不过是 操纵的 单元不同,第一个问题是操纵的是语句,这个问题是操纵的 完整的一行或几行。

shift + v  ->  ngg或nj或nk -> d或y -> ngg -> p

shift+v进入到line mode中,然后ngg为选中多行,也可以使nj向下移动,n为数字表示向下选中n行。然后删除或是复制,找到另外一个地方进行粘贴p

如何将某几行统一的快速左移和右移?

shift + v -> ngg或nj或nk ->  >       快速右移

shift + v -> ngg或nj或nk ->  <       快速左移

block mode 应用

可用于验证ansible yaml或k8s yaml等文件的缩进情况,提早发现问题

ctrl + v -> ngg或njjj或nk或nl或nh 选中

通过高亮情况来查看是否缩进正常,如果不使用这种方式单凭肉眼去看比较困难。

多行增加注释和多行取消注释

可参照本文第11个问题

多行自动缩进

可参照本文第12个问题

1. 如何在两个不同的文件之间进行复制和粘贴呢?

这是我们经常在Linux下的操作,通过实践我发现了一个非常好的方法。

1.  vim  a.txt  b.txt         //使用vim打开两个文件分别为 a.txt 和 b.txt,当然也可以是三个或者多个

一共三个命令:   :n  :N   :files

:n  编辑下一个档案

:N 编辑上一个档案

:files 查看vim开启的多个文档

在 a.txt中进行复制,比如: 10yy 复制十行数据,然后 :n  切换到下一个档案,然后到b.txt的指定位置,执行p粘贴操作,最后保存退出即可。

这是将文件的内容读入到计算机的内存中,即 vim buffers。

还有一种方式是使用选项卡,可以同时打开多个文件

:tabnew <filename> 在新选项卡中打开指定的文件。

:tabnext  切换到下一个选项卡,或快捷键 gt

:tabprev  切换到上一个选项卡,或快捷键gT

:tabclose 关闭当前选项卡

ngt   切换到第n个选项卡,不用输入:

问题:键盘复制 a.txt 从某2行到某20行,然后切换到第二个文件的30行进行粘贴:

步骤一: 2gg -> V -> 20gg -> y       注意: 这里是大写的V,按行来进行选择。如果是剪切,不用y,使用d,还要保存一下a.txt

步骤二:  :n                                     切换到下一个文件

步骤三:30gg -> p                           转到第30行,然后粘贴即可

问题:键盘复制 a.txt 全部复制,然后:N切换,最后粘贴即可。

全选(高亮显示):命令模式  gg  ->  V  ->  G    注意这里是大V,是按行来进行选择

全部复制:命令模式gg  ->  y  ->  G   

删除从当前行到最后一行:命令模式  d    -> G   删除内容包括当前行。

或  :7,$d     假设当前在第7行,删除第7行至最后一行,$代表最后一行        

删除当前行到第一行: 命令模式   d -> gg    删除内容包括当前行。

或   : 1, . d       删除第一行到当前行,  "." 代表当前行, "$"代表最后一行

全部删除:命令模式  gg  ->  V  ->  G -> d   注意这里是大V,是按行来进行选择

2. 有时候编写一个大的文件,需要在后面对照这个文件前面的数据,最笨的方法就是前后移动,然后进行查看。其实有一个方法,我们可以通过 :sp 命令进行分割窗口,使同一个文件有两个不同的窗口。

1.   vim  a.txt

然后输入 :sp  或者  :sp  b.txt      水平方向打开相同文件或另一个文件

               :vsp 或者  :vsp b.txt     垂直方向打开相同文件或另一个文件

2. 具体操作如下

:sp [filename]

:vsp 

[filename]

开启一个新窗口,如果有加 filename, 表示在新窗口开启一个新档案,否则表示两个窗口为同一个档案内容(同步显示)。

:sp 水平方向打开

:vsp 垂直方向打开

[ctrl]+w+ j
[ctrl]+w+↓
按键的按法是:先按下 [ctrl] 不放, 再按下 w 后放开所有的按键,然后再按下 j (或向下箭头键),则光标可移动到下方的窗口。
[ctrl]+w+ k
[ctrl]+w+↑
同上,不过光标移动到上面的窗口。
[ctrl]+w+ q其实就是 :q 结束离开啦! 举例来说,如果我想要结束下方的窗口,那么利用 [ctrl]+w+↓ 移动到下方窗口后,按下 :q 即可离开, 也可以按下 [ctrl]+w+q 啊!

本文参考了鸟哥私房菜的内容。

当从windwos的文件上传到了Linux里面,导致很多看到了很多 ^M符号,如何替换呢?

使用vim打开这个文件:

#vi abc.txt

:1,$ s/^M//g

^M 输入方法: ctrl+V ,ctrl+M

点击回车即可。

3. 单个文件中的内容复制,打开命令模式:

:1,20 co 25                   //把本文件中的第1-20 行复制到25行下边

4.命令模式下,跳到指定行

ngg/nG (跳转到文件第n行,无需回车)  或者 :n (跳转到文件第n行,需要回车)

5.命令模式下,另起一行,并进入到编辑模式。

o    向下面另起一行

O   向上面另起一行

cw 替换从光标所在位置后到一个单词结尾的字符

r     以覆盖方式替换1个字符(不进入输入模式)

R    以覆盖方式替换多个字符(不进入输入模式)

s     替换当前光标所在的字符,并进入到输入模式,不以覆盖方式进行

cc   替换当前整个行

S     替换当前整个行

C     替换当前光标所在的字符到这一行的末尾,并进入到输入模式

^ 移动到本行第一个不是blank字符的位置(所谓blank字符就是空格,tab,换行,回车等),向上的箭头,Ctrl+6

u  恢复上一次改变(undo)

ctrl + r  重做(redo)

.  重复上一个命令

N<command>  重复某个命令N次,例如 3p  重复粘贴3次

6. 同一行的左右的快速移动

3h  :  同一行内 左移3个字符

3l   :  同一行内右移3个字符

w 或 W 下一个单词的开头,光标向后移动一个单词

b  或 B  上一个单词的开头,光标向前移动一个单词

e  下一个单词的结尾:如果当前光标所在的字符是最后一个,按e则是下一个单词的结尾,如果当前光标所在是这个单词的其他字符,按e则是这个单词的结尾

* 和 #:  匹配光标当前所在的单词,例如将鼠标放置在plugin上,这样按下 * 或 # 则可以在 <plugin> xxxx xxxx </plugin> 之间进行快速移动。

*  移动光标到下一个匹配单词,但实际键盘的输入为  shift + 8

#  移动光标到上一个匹配单词,但实际键盘的输入为 shift + 3

 |   移动光标到第1列,这不是l ,是 竖线,需要使用shift + \ 来输入。

n|  移动光标到第n列

3w 向后移动三个词

5j 向下移动5行

7dw 删除7个词

7. 如何复制第2行的某个字符串(假设长度为10)到第3行?

首先将光标移动到这个字符串的开头,然后 v ->  10l  -> y -> 3gg -> w -> p

v是可视化选择,10l左移10个字符,y是复制,3gg是切换到第三行,w是在第3行将光标移动到需要粘贴的位置,这里仅是示例而已,真实情况你可能需要多个w来移动到多个字符串,或20l向右移动20个字符,然后p是粘贴。

比如我们现在有四行java的代码

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

当我想从第一行中复制 import org.springframework.boot   然后粘贴到第二行作为引入配置然后再输入.autoconfigure.SpringBootApplication;   这样我可以不用写那些重复的代码,可以很省时省力,那我如何操作呢。

gg  ->  v  ->  fS -> y  ->  :put -> $ -> a

gg 首先让光标到一行,

v 进入视图模式,

fS 找到下一个S的字符处(即 SpringApplication),

:put  用于粘贴到第二行,这个命令有点陌生; 当然你也可以是  o -> esc -> p

$  进入第2行的行尾

a  然后可以使用键盘输入 autoconfigure.SpringBootApplication;等等了

如下几个命令的解释:

  • fa → 到下一个为a的字符处,你也可以fs到下一个为s的字符,只能搜字符不能搜字符串
  • t, → 到逗号前的第一个字符。逗号可以变成其它字符。
  • 3fa → 在当前行查找第三个出现的a。
  • F 和 T → 和 f 和 t 一样,只不过是相反方向。
  • ,和 ;分别代表上一个匹配和下一个匹配的快捷键,非常好用

综上: 同一行内 可以使用 w、  10l、 fX 来快速移动光标

8.将内容复制到系统的剪贴板

上述几个步骤都是复制到vim的寄存器,无法与外界进行交互。

vim --version | grep "clipboard"

clipboard前面有一个减号,说明不支持

打开vim输入:reg查看vim的寄存器

安装vim-gnome

8.从外部文件复制数据到vim的文件中会出现直接粘贴有时会不对齐,缩进不正确,尤其是yaml文件,多余的空格或缺少空格会导致整个yaml文件不能用。

解决方法:  :set paste 再按i或o进行粘贴,格式就会正确

也可以由paste状态转换为nopaste,  :set nopaste ,这样就恢复了原来的设置。

10.整体将代码进行左移和右移

shift + > + > (向右移动) ,shift + < + <(向左移动)  //  需要按两下 >>  <<

:10,15>
第10行至第15行向右整体移动
:20,80<
第20行至第80行反缩进

11.多行增加注释和多行删除注释

多行增加注释:

ctrl + v  ->  ngg  -> I(大写的i)  -> 输入//  -> esc

第一步首先 ctrl+v 进入到 visual block模式,第二步然后依次选择要增加注释的行,可以使用j向下移动选择,也可以使用  ngg瞬间移动到第n行,其中n为第几行; 第三步是 I (这是大写的i,insert插入的意思),然后根据你的编程语言来 输入 // 或 # 进行注释,第四部 按 esc键即可。

同理这个功能除了多行增加注释//,也能插入其他字符,比如你 输入 123,则在多行的前面增加了123

多行删除注释

ctrl + v ->  ngg  -> x -> .

第一步首先 ctrl+v 进入到 visual block模式,第二步然后依次选择要增加注释的行,可以使用j向下移动选择,也可以使用  ngg瞬间移动到第n行,其中n为第几行; 第三步是x 删除,然后根据你的编程语言来删除注释,每次只能删除一个字符,例如:如果是Java则需要进行第四步,如果是python则完成,第四步 按  .  重复操作一次即可。

12. 自动缩进

ctrl + v  -> ngg -> =

第一步首先 ctrl+v 进入到 visual block模式,第二步 ngg来选择你的整个函数,第三步 =

你会发现vim直接给你自动的进行了标准缩进,你无需手动修改。

13. 翻页

翻下一页,Ctrl+f键 ,f 的英文全拼为:forward

              也可以使用 pagedown键

翻上一页,Ctrl+b键,b 的英文全拼为:backward

               也可以使用pageup键

翻下半页,Ctrl+d键,d 的英文全拼为:down

翻上半页,Ctrl+u键,u 的英文全拼为:up  

14. 快速删除全局line中的某些字符

:g/<pattern>/d

g代表是global全局,d是删除, <pattern>代表正则表达式,整条语句是说 将文件中每行匹配到<pattern>的行进行删除操作。

:g!/<pattern>/d

如果是将不匹配的删除,可以在语句中增加!代表反义,即将不匹配的每一行进行删除操作。

  • :g/foo/d    将删除包括foo字符串的每一行
  • :g!/foo/d   将删除不包括foo字符串的每一行
  • :g/^#/d       将删除开头为 # 的行,例如将python代码中的注释删除
  • :g/^$/d       将删除 所有空行,这个模式 ^$ 匹配所有空行,缺点是删除不了有多个空格的行
  • :g/^\s*$/d 将删除包含开头 \s的空格的行,*代表匹配前面的子表达式0次或多次

所以如果你使用命令删除文件中所有的空行,最好使用最后一个命令。

15. 快速将多行变一行

当我写代码的时候,我写完了<groupId> ,我复制yy了这一行并粘贴p了,在第二行中添加/ ,于是这时候有两行<groupId>,  我使用O 再将 具体命名写上,比如 com.example  整体如下图所示:

<groupId>
    com.example
</groupId>

我想将这三行快速变为一行,这在java项目的pom.xml中非常常见,J是将下一行与当前行合并但保留空格,而gJ是将下一行与当前行合并但不保留空格

首先切换为visual line模式,然后3j选中这三行,最后J将其粘合为一行。

shift + v  ->  3j  -> J

或将光标放置在 <groupId>那一行直接 3J也是可以

<groupId> com.example </groupId>

这样我们既少写了代码又能快速合并为一行,简单又快捷。

也或者:

:1,3 join   或 :1,3 j

1,3 是指 第1行到第3行合并为一行

重点:   gJ是将下一行与本行合并,且无空格。

当你 <groupId>的左侧、com.example的左侧、</groupId>的左侧 都没有空格,也就是说定格书写,使用 3gJ可以将其合并为一行,且没有多余的空格。

如果你的 <groupId>的左侧、com.example的左侧、</groupId>的左侧 有空格或tab,使用3gJ可合并为一行,但多余的空格将会保存。

整体如何操作?

当你写第一行<groupId>时候,直接定格写,然后定格写 com.example,再定格写 </groupId>

在直接3gJ将其合并为一行且没有多余的空格,最后使用ngg切换到<dependency>行,按下shift + v,然后xgg选择到</dependency>选中,使用 = 将其对其缩进,这样简单又方便。

其中 ngg是<dependency>所在的第n行,xgg是</dependency>所在的第x行

16. 进入编辑模式多种快捷键

一般我们都会使用a/A、i/I、r/R、o/O来进入编辑模式

a: 在当前光标所在位置之后插入随后输入的文本

A: 直接到行尾再进入到编辑模式

i :在当前光标所在位置插入随后输入的文本,光标后的文本相应向右移动

I : 在光标所在行的行首插入随后输入的文本,行首是该行的第一个非空白字符,相当于光标移动到行首执行 i 命令

r : 在当前光标所在位置进行替换

R : 进入替换并光标向后移动依次进行替换,并直到esc退出替换

s : 删除当前光标所在的字符,并进入到编辑模式

cc : 删除当前光标所在的行,并进入到编辑模式

C  : 删除当前光标到行尾的所有字符,并进入到编辑模式

17. 在输入模式下,删除 和 缩进 的操作

vim 输入模式下

 ctrl-h 删除前一个字符,与 backspace一样

 ctrl-w 删除前一个字

 ctrl-u  删除当前光标到行首的部分

 ctrl-t  缩进当前行,右移,和 命令模式下的shift + > + >

 ctrl-d  反缩进当前行,左移,和 命令模式下的shift + < + <

18. 上下移动行

:m .+1 回车    将当前行 下移一行, . 代表当前行,+1代表向下,m代表移动

 :m .-2 回车    将当前行 上移两行

19. 宏录制

宏录制: qa 操作序列 q@a@@

  • qa 把你的操作记录在寄存器 a。
  • 于是 @a 会replay被录制的宏。
  • @@ 是一个快捷键用来replay最新录制的宏。

q代表开始录制,也代表结束录制,例如: q1 代表开始录制并将操作记录在寄存器1中

i1<ESC>q1yyp<C-a>q98@1

i 代表输入,进入到编辑模式

1 代表输入1

<ESC> 代表退出编辑模式,进入到命令模式

q1 代表开始录制并将操作记录在寄存器1中

yy 代表复制当前行,这里也可以使用 Y进行复制,都是一样的

p 代表粘贴已复制的行

<C-a> 代表为Ctrl+a,代表自增1

q 代表 结束录制

98@1 代表重复98次 在1中录制的命令

于是得到 1到100行

20. 将一个ip进行自增

比如: 22.244.161.1 我想一下增加到22.244.161.255,类似于Excel下拉数字自增

答案: 利用宏特性实现下拉快速自增

i22.244.161.1<ESC>q1yyp$<C-a>q253@1

首先i进入输入状态,然后输入22.244.161.1然后退出输入状态,按q开始录制到1这个变量里面,然后yyp复制并粘贴,此时有两行22.244.161.1,光标在第二行的开头,按$移动到最后一位,然后通过ctrl-a进行自增1,我们发现第二行变成了22.244.161.2,然后按q结束录制。

最后我们使用1这个变量的宏重复253次即可实现自增,253@1即可,如图所示:

21. 在多行后面同时补充多行数据

其实前面第11个问题多行增加注释和多行删除注释 已经说明了,但是第11个问题是在每行的开头新增"//",而有时候我们想在末尾增加数据,增加用户名和用户密码。

例如:我们在第20个问题的基础上,新增用户名和用户密码,比如 用户名为test,密码为12345678,因为ip末尾有的占用1位(1-9),有的占用2位(10-99),有的占用3位(100-255),所以一定要注意空格

gg移动到第一行,然后ctrl-v进入块模式,然后G选中最后一行,然后通过 $右移动到末尾,然后按A,此时输入:test:12345678 然后ESC即可输入完成。

gg<C-v>G$A:test:12345678<ESC>

如果想同时删除多行的某一列数据:通过快选择 ctrl-v,然后进行矩阵选择,通过h或l进行列的选择,通过gg或ngg或G进行行选择,选择某几行到某几列,然后按d即可删除。

这里为什么使用:进行分隔,因为可以使用awk -F ':' '{print $1}'进行读取ip,可以使用awk -F ':' '{print $2}'进行读取用户名,可以使用awk -F ':' '{print $3}'进行读取密码,而/etc/passwd也是使用冒号这样分隔不同的信息。

同时修改多行数据: 通过ctrl-v进入可视模式,然后按上下左右键选择多行多列,然后按c,进行输入,最后<ESC>即可。

22. buffers 一些操作

当用户使用vim打开某个文件时候,将从磁盘读取文件内容到内存中,这个称为 vim buffers,其实就是被打开的文件。

vim $(git diff --name-only)

主要的buffers的操作:

:buffers 或 :ls  或 :files 显示目前已打开的文件

:b {filename} 切换到 filename 这个buffer,使用tab自动补全非常好用

:bd  关闭当前的buffer

:bn  切换到下一个buffer

:bp  切换到上一个buffer

:b#  切换到上一个访问过的buffer

:bf  切换到第一个buffer

:bl  切换到最后一个buffer,这是小写的L,不是1

:bm  切换到下一个被修改的buffer

:bN  切换到第N个buffer,N为数字

:sb 1  打开1号buffer的split,默认是上下分隔,水平分隔

:sb {bufname} 以split打开filename

:vs 1  打开1号buffer的split,是左右分隔,竖向分隔

<C-w>k  移动光标到上面的窗口

<C-w>j   移动光标到下面的窗口

<C-w>c  关闭当前的某个窗口

:close 关闭当前的某个窗口

:bd {filename} 关闭filename文件

:bd n 关闭 第n个文件

23 修饰语

修饰语有 i,表示“内部”或者“在内”,和 a, 表示“周围”。

ci(  改变当前括号内的内容

ci[  改变当前方括号内的内容

da'  删除一个单引号及内部的字符串

24. 命令行

1. tab方式

:tab ter          //以tab方式打开terminal

ctrl+w gt 或 ctrl+w gT // 在文档和命令行之间进行切换

ctrl+d 关闭命令行

2. buffer方式(非常好用)

:ter                //以buffer方式打开terminal,将会显示上下两层

ctrl+w K/J     // 上下切换

ctrl+w jhlk     // 在各窗格之间进行切换

:vert ter         // 以buffer方式打开terminal,将会显示左右

ctrl+w H/L     // 左右切换

ctrl+w :          // 在底部的命令行进行输入命令

从 cmd复制一些信息 到 文件中,将磁盘的一些信息复制到文件中

# df -h    输出一些磁盘信息

ctrl+w N 进入命令行正常模式(后续可使用i进行恢复),通过v/V/Ctrl-v进行选择并复制y

ctrl+w w或j 切换到文件中,找到位置,使用p进行粘贴即可。

从文件中复制一些信息到命令行进行执行

在文件中通过v/V/Ctrl-v进行选择并复制y

ctrl+w w或j 切换到命令行中,使用ctrl+w ""  进行粘贴

ctrl+d 关闭命令行

25. buffer/window/tab区别和联系

一个buffer是一个文件加载到在内存用于编辑的一个临时文件,而原始文件并没有改变,直到你把buffer写入到文件中;
一个window是一个视窗(viewport), 是查看buffer的视窗窗口,可以多个window查看一个buffer,或者多个buffer有多个window查看;
一个tab标签页面是几个window视窗窗口的集合,也就是说一个tab标签页可以分为多个视窗window窗口;           

<C-w> n  新建一个windows及一个空文件

<C-w> s  将当前的窗口水平分隔为两个

<C-w> v  将当前的窗口垂直分隔为两个

<C-w> q  关闭当前的窗口

<C-w> K  移动当前的window到顶部

<C-w> J   移动当前的window到底部

<C-w> H  移动当前的window到左侧

<C-w> L   移动当前的window到右侧

<C-w> :    当你在命令行下的时候,输入<C-w> : 然后才能在底部输入命令,否则是将键入的信息输入到命令行中,而不是命令。

:res[ize] -N  将当前窗口高度减去N,N是数值

:res[ize] +N 将当前窗口的高度增加N,N是数值

:res[ize]  N< 将当前窗口的宽度减少N,N是数值

:res[ize]  N> 将当前窗口的宽度增加N,N是数值

26. 命令模式下快速将一行代码快速换行

命令模式不是底部模式

首先找到要换行的位置,然后 R<Enter>

27. 移动光标到某个位置

zz   将当前光标所在的行在屏幕上居中显示,这在写代码时候非常有用,避免了使用j/k进行移动了

zt    将当前光标所在的行在屏幕上顶部显示

zb   将当前光标所在的行在屏幕上底部显示

<C-b>  向后移动一页或向上移动一页

<C-f>   向前移动一页或向下移动一页

<C-u>  向后移动半页或向上移动半页

<C-u>  向前移动半页或向下移动半页

H          将当前的光标移动到屏幕的顶部

M         将当前的光标移动到屏幕的中部

L          将当前的光标移动到屏幕的底部

更详细的教程请参考: 简明 Vim 练级攻略 | 酷 壳 - CoolShell

本文标签: 记不住 操作 vim