使用Vim打开和保存文件是最常用的操作,介绍使用edit命令通过文件路径来打开文件,使用write命令保存文件,当文件路径不存在或用户权限不匹配时,使用write命令调用外部shell程序完成操作。
1. edit命令打开文件
Vim命令 :edit
(缩写形式为 :e
) 可以通过文件的绝对路径或相对路径来打开文件。
如果想打开的文件和当前活动文件缓冲区中的文件在同一个目录里,可以使用 :edit %:h<Tab>
命令。
%
符号代表活动缓冲区的完整文件路径,:h
修饰符会去除路径中的文件名,但保留路径中的其他部分。因此,输入的 %:h<Tab>
会被展开为当前文件所在目录的路径。
Vim命令 %
和 :h
在命令行模式下具有特殊含义,可用于高效操作与Vim文件路径相关的功能。
2. 把文件保存到不存在的目录
如果使用 :edit {file}
命令指定了一个不存在的文件路径,Vim 会创建一个新的空白缓冲区。在新建的空白缓冲区中按 <Ctrl-g>
时可以看到该缓冲区被标识为新文件。然后,当执行 :write
(缩写形式为 :w
) 命令保存该缓冲区时,Vim 会尝试将此缓冲区的内容写到创建该缓冲区时所指定的文件路径中。
如果指定的文件路径不存在时,Vim会因为找不到对应目录而显示出错信息 “无法打开并写入文件”。
此时,一个常用的Vim使用技巧是调用外部的 mkdir 程序新建目录。在Vim命令行模式下执行 :!mkdir -p %:h
命令后可以执行 :write
命令保存新建的文件。
:!mkdir
表示调用外部的 mkdir 命令,-p
参数使 mkdir 创建任何不存在的中间目录,而 %:h
表示当前活动缓冲区对应文件所在目录。
注:<Ctrl-g>
命令用于显示当前文件的文件名及状态,
3. 以超级用户权限保存文件
在使用Vim工作时,有时会遇到需要以root身份保存文件的场景。
例如,假设当前用户为 vim,打开 /etc/hosts
文件查看当前host配置后需要新增一个域名解析 vim.ink 127.0.0.1
。
首先,使用 Go
命令在hosts文件末尾新建内容后,使用 :write
命令尝试保存结果,此时Vim会报错 “E45:已设定选项 ‘readonly’ (请加 ! 强制执行)”。按照提示,使用命令 :write!
强制执行write命令时,Vim仍然报错 “ E212: 无法打开并写入文件”。
这说明现在的问题是当前用户没有写 /etc/hosts
文件的权限。
为了不退出Vim而保留已有修改,可以使用Vim命令 :write !sudo tee % > /dev/null
,然后按Vim的提示输入vim用户的密码并按 L 键重新将该文件加载到缓冲区即可。
这条命令是如何工作的?
首先,:write !{cmd}
命令会把当前文件缓冲区的内容作为标准输入传给指定的{cmd},{cmd} 可以是任何外部程序 (vim命令行模式下执行命令 :h :write_c
可查看更多内容)。
其次,在 Vim 命令行中,%
符号会展开成当前文件的完整路径,因此上面的命令可以展开为 :write !sudo tee /etc/hosts > /dev/null
所以,上面这条命令会把当前文件缓冲区的内容当作标准输入传递给linux的 tee
命令,以超级用户权限运行 tee
命令重定向到文件 /etc/hosts
中,从而实现了不重启Vim而以超级用户权限保存文件的需求。
注:linux命令tee表示将内容重定向到指定的文件并重定向内容副本到标准输出。