在 Vim 中高效执行 Linux 命令:完整指南

Vim 不仅仅是一个文本编辑器,它更是一个强大的文本处理环境。对于开发者和系统管理员而言,一个常见的需求是在不离开 Vim 编辑器的情况下快速执行外部的 Linux 命令。无论是需要检查文件列表、编译代码、运行版本控制命令,还是将命令的输出直接插入到当前编辑的文档中,Vim 都提供了灵活且高效的方式来实现。

强行退出 Vim 去执行命令再重新打开,会严重打断工作流。掌握在 Vim 内部执行命令的技巧,可以让你保持“心流”(Flow),显著提升工作效率。本篇博客将深入探讨多种在 Vim 中执行命令的方法,包括其适用场景、最佳实践以及详尽的示例。

目录#

  1. 基本方法::! 命令
  2. 读取命令输出到缓冲区::r !
  3. 将缓冲区内容作为命令输入::w !
  4. 在 Shell 中暂离 Vim::shCtrl-Z
  5. 常用场景与最佳实践
  6. 总结
  7. 参考

基本方法::! 命令#

这是最直接、最常用的方法。它的作用是暂停 Vim,执行指定的外部命令,并在命令结束后按回车键返回 Vim

语法#

:!command

例如,你想查看当前目录的文件列表,可以输入:

:!ls -la

执行后,你会看到 ls -la 的输出显示在屏幕上,按回车后即可返回 Vim 继续编辑。

高级用法:使用当前文件或缓冲区内容#

:! 命令中,Vim 提供了一些特殊的占位符,使得命令能与当前编辑的文件交互:

  • %: 代表当前文件的文件名。
  • #: 代表轮换文件(Alternate File)的文件名。
  • %:p: 代表当前文件的完整绝对路径。

示例#

  1. 编译当前正在编辑的 C 文件:

    :!gcc % -o hello

    这个命令会使用 gcc 编译当前文件(% 会被替换为 hello.c),并生成名为 hello 的可执行文件。

  2. 检查当前文件的语法(例如 Python):

    :!python -m py_compile %
  3. 查看当前文件的绝对路径:

    :!echo %:p

读取命令输出到缓冲区::r !#

当你需要将某个命令的输出直接插入到当前光标所在位置时,:r !command 是你的最佳选择。rread 的缩写。

语法#

:r !command

示例#

  1. 在文档中插入当前日期和时间:

    :r !date

    执行后,类似 Wed Oct 25 15:30:00 CST 2023 的日期字符串会被插入到光标下一行。

  2. 将系统日志插入到文档中:

    :r !tail -n 10 /var/log/syslog

    这会将系统日志的最后 10 行插入到当前光标位置。

  3. 插入当前目录的文件列表:

    :r !ls -la

将缓冲区内容作为命令输入::w !#

这个技巧相对进阶但非常实用。它允许你将当前缓冲区(或部分文本)的内容发送给一个外部命令作为输入,而不需要保存文件。wwrite 的缩写。

语法#

:.w !command    " 将当前行发送给命令
:5,10w !command " 将第5到第10行发送给命令
:%w !command    " 将整个文件内容发送给命令

示例#

  1. 对选中的代码进行排序: 假设你选中了几行无序的文本(使用 V 进入可视模式选择),然后执行:

    :'<,'>w !sort

    这会将选中的文本传递给 sort 命令,你会在下方看到排序后的结果,但原文本不会被修改。如果你想用排序后的结果替换原文本,可以使用 :’<,’>!sort(注意没有 w),这被称为“过滤”。

  2. 检查 Python 代码的语法而不运行它:

    :%w !python -m py_compile

    将整个文件内容传递给 Python 编译器,如果有语法错误,错误信息会显示在下方。

  3. 计算当前文件的行数、单词数:

    :%w !wc

在 Shell 中暂离 Vim::shCtrl-Z#

有时你需要执行一系列复杂的命令,临时切换到 Shell 更方便。

方法一:使用 :sh 命令#

输入 :sh,Vim 会为你启动一个子 Shell。你可以在此执行任意多的命令。完成后,输入 exit 或按 Ctrl-D 即可返回到 Vim,并且之前的编辑状态会被完整保留。

方法二:使用 Ctrl-Z(更常用)#

这是在大多数 Unix-like 系统中通用的方法。按下 Ctrl-Z 会将 Vim 进程挂起(Suspend)到后台。

然后你会回到父 Shell。此时 Vim 处于暂停状态。你可以执行任何命令。要返回到 Vim,只需在 Shell 中输入 fg(foreground 的缩写)。

优点Ctrl-Z/fg 组合键操作速度极快,是许多资深用户的首选。

常用场景与最佳实践#

文件与目录操作#

  • 场景:编辑文件时,需要快速创建新目录。
    • 做法:!mkdir -p new_directory
  • 场景:查找项目中的某个文件。
    • 做法:!find . -name "*.js" | grep component

编译与运行代码#

  • 场景:写 C++ 代码时,快速编译并运行。
    • 做法
      :!g++ % -o %< && ./%<
      这里 %< 代表当前文件名去掉扩展名的部分(例如 main.cpp 变成 main)。这是一个非常高效的组合命令。

代码格式化#

  • 场景:使用 clang-format 格式化当前 C++ 文件。
    • 做法:%!clang-format (这是过滤操作,用命令输出直接替换整个缓冲区)
  • 场景:格式化选中的 JSON 代码块。
    • 做法:在可视模式下选中 JSON 文本,然后执行 :'<,'>!python -m json.tool:'<,’>!jq

与版本控制集成#

  • 场景:在编辑时,想查看当前文件的 Git 提交历史。
    • 做法:!git log --oneline %
  • 场景:将当前文件添加到 Git 暂存区。
    • 做法:!git add %

总结#

在 Vim 中执行外部命令是其强大功能的核心之一。你可以根据目的选择合适的方法:

方法命令用途
简单执行:!command执行命令并查看输出,不修改文件。
插入输出:r !command将命令输出插入到光标位置。
发送输入:[range]w !command将文本作为标准输入发送给命令。
过滤文本:[range]!command用命令的输出替换指定范围的文本。
临时离开Ctrl-Z / :sh挂起 Vim 进入 Shell,执行复杂任务。

熟练掌握这些技巧,将使 Vim 从一个单纯的编辑器升级为你工作流的控制中心,让你真正做到“运指如飞,不离键盘”。

参考#

  1. Vim 官方文档::h :!
  2. Vim 官方文档::h :r
  3. Vim 官方文档::h :w_c
  4. Vim 官方文档::h :range
  5. man bash(关于作业控制 jobs, fg, bg