如何从命令提示符运行一系列vim命令

时间:2014-04-23 05:01:56

标签: shell vim command-prompt

我有四个文本文件A.txt,B.txt,C.txt和D.txt 我必须在所有这些文件中执行一系列vim编辑。 目前我正在做的是打开每个文件并逐个执行相同的vim命令。

是否可以创建一个我可以从命令提示符运行的脚本文件,意味着无需打开vim编辑的实际文件。

例如,如果我在vim编辑器中打开A.txt文件后必须执行以下vim命令:

:g/^\s*$/d
:%s/^/[/
:%s/\(.*\)\(\s\+\)\(.*\)/\3\2\1
:%s/$/]/
:%s/design/test/

是否可以制作脚本文件并将所有这些命令包括gvim A.txt(文件中的第一个命令)。 并编辑从命令提示符运行脚本文件。

如果有可能请告诉我怎么做,请告诉我一次如何处理单个文件和一次多个文件?

5 个答案:

答案 0 :(得分:24)

vim -c <command> Execute <command> after loading the first file

你描述的是什么,但你一次只能做一个文件。

所以,在windows shell中......

for %a in (A,B,C,D) do vim -c ":g/^\s*$/d" -c "<another command>" %a.txt

POSIX外壳很相似,但我现在还没有机器在我面前。

我想你可以一次加载所有文件并执行它,但是需要在每个文件的vim命令行上重复命令,类似于

vim -c "<command>" -c "<command>" -c ":n" (repeat the previous -c commands for each file.)  <filenames go here>

编辑:2014年6月8日: 仅仅是一个FYI,我几分钟前发现了这一点。

vim有命令bufdo对编辑器中加载的每个缓冲区(文件)执行操作。查看bufdo命令的文档。在vim中,:help bufdo

答案 1 :(得分:18)

在命令行上直接传递给Vim的-c命令的数量限制为10,这不是很易读。或者,您可以将命令放入单独的脚本中并将其传递给Vim。以下是:

无声批处理模式

对于非常简单的文本处理(即使用Vim就像增强的&#39;或者&#39; awk&#39;,可能只是受益于:substitute命令中增强的正则表达式) ,使用 Ex-mode

REM Windows
call vim -N -u NONE -n -es -S "commands.ex" "filespec"

注意:静默批处理模式(:help -s-ex)会混淆Windows控制台,因此您可能需要在Vim运行后执行cls清理。

# Unix
vim -T dumb --noplugin -n -es -S "commands.ex" "filespec"

注意:如果"commands.ex"文件不存在,Vim将等待输入;更好地检查它的存在!或者,Vim可以从stdin读取命令。您还可以使用从stdin读取的文本填充新缓冲区,如果使用-参数,则从stderr读取命令。

完全自动化

对于涉及多个窗口的更高级处理,以及Vim的真实自动化(您可以与用户交互或让Vim运行以让用户接管),请使用:

vim -N -u NONE -n -c "set nomore" -S "commands.vim" "filespec"

这里是使用过的参数的摘要:

-T dumb           Avoids errors in case the terminal detection goes wrong.
-N -u NONE        Do not load vimrc and plugins, alternatively:
--noplugin        Do not load plugins.
-n                No swapfile.
-es               Ex mode + silent batch mode -s-ex
                Attention: Must be given in that order!
-S ...            Source script.
-c 'set nomore'   Suppress the more-prompt when the screen is filled
                with messages or output to avoid blocking.

答案 2 :(得分:17)

使用您希望在脚本中保存的每个文件上运行的所有命令,例如&#34; script.vim&#34;,您可以在一个文件上执行该脚本(如其他人所提到的):

vim -c "source script.vim" A.txt

更进一步,您可以将文件保存在脚本的末尾,方法是在脚本本身中放置一个:w命令,或者从命令行传递它:

vim -c "source script.vim | w" A.txt

现在,您可以使用argdo命令在Vim上对多个文件运行任何命令。所以你的命令变成了:

vim -c "argdo source script.vim | w" A.txt B.txt C.txt D.txt

最后,如果你想在每个文件上运行脚本后退出Vim,只需添加另一个命令退出:

vim -c "argdo source script.vim | w" -c "qa" A.txt B.txt C.txt D.txt

答案 3 :(得分:6)

请尝试以下语法:

ex foo.txt <<-EOF
  g/^\s*$/d
  %s/^/[/
  %s/\(.*\)\(\s\+\)\(.*\)/\3\2\1
  %s/$/]/
  %s/design/test/
  wq " Update changes and quit.
EOF

ex命令相当于vim -E。添加-V1以获得详细输出。

替代单线语法例如:

ex +"g/^\s*$/d" +"%s/^/[/" +"%s/design/test/" -cwq foo.txt

要从文件加载命令,请使用-s cmds.vim

您也可以使用shebang for Vim to parse the file from the argument

有关更多示例,请参阅:

答案 4 :(得分:2)

JimR和Ingo为您的用例提供了出色的答案。

只是要添加一种方法,但是,您可以使用我的vimrunner插件编写ruby中的交互脚本:https://github.com/AndrewRadev/vimrunner

示例:

vim = Vimrunner.start

vim.edit "file.txt"
vim.insert "Hello"
vim.write

vim.kill

这对于更复杂的交互非常有用,因为您可以充分利用编程语言。