在shell脚本中执行Vim命令

19

我正在编写一个Bash脚本,它可以运行一个命令行程序(Gromacs),保存结果,修改输入文件,然后再次循环执行。

我尝试使用Vim来修改输入文本文件,但我没有找到一种在打开我的输入文件后从.sh文件中执行内部Vim命令(如:1234、w、x、dd等)的方法。

是否有一种实用的方式可以从shell脚本中执行Vim命令?


你确定需要使用 vim 而不是其他编辑器,比如 sed 吗?你能否在 vimex 模式下使用它,该模式不使用全屏幕(因此更适合用于脚本)?你在编写脚本时到底想做什么编辑操作? - Jonathan Leffler
3个回答

18

我认为 vim -w/W 和 vim -s 是你要找的。

你也可以使用 vim -w test.keys input.file 来记录"Vim操作/按键序列"。你也可以编写 test.keys,例如将以下内容保存在文件中:

ggwxjddZZ
这样做就可以了:
Move to the first line,
move to the next word,
delete one character,
move to the next line,
delete the line, and
save and quit.

有了这个test.keys文件,你可以做到:

vim -s test.keys myInput.file

上述操作将处理您的“myInput.file”并进行保存。您可以在shell脚本中添加该行。

VimGolf使用相同的方式保存用户的解决方案。


15

你可以通过-c标志来编写Vim脚本。

vim  -c "set ff=dos" -c wq mine.mak
然而,这只能帮助你到这个程度。
  • 从您输入的命令来看,似乎您正在尝试运行一些普通命令。 您需要使用:normal。例如::norm dd
  • 在命令行上编写所有这些内容可能会导致麻烦。 我建议您创建一个Vim文件(例如commands.vim),然后通过-S使用:source
  • 您可能想要掌握并符合Vim的ex命令。 可以查看:h ex-cmd-index

因此,您最终将得到像这样的东西。将所有Vim命令放在commands.vim文件中。

vim -S commands.vim mine.mak

您可能也想尝试使用sed和/或awk来进行文本处理。


这正是我一直在寻找的。我已经有了一个适用于vim的解决方案,所以我不想选择另一种语言/工具。 - Gustavo Matias

8

替代品

除非你确实需要特殊的Vim功能,否则最好使用像sedawk或Perl / Python / Ruby / 你喜欢的脚本语言在这里这样的非交互式工具

话虽如此,你可以非交互地使用Vim:

无声批处理模式

对于非常简单的文本处理(即像增强版的'sed'或'awk'一样使用Vim,也许只是在一个: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可以从标准输入中读取命令。如果使用“-”参数,您还可以从标准错误中读取命令,并使用从标准输入中读取的文本填充新缓冲区。
完全自动化:对于涉及多个窗口和真正自动化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.

我确定这就是我需要的,但如果我执行 vim -c "dd" myfile.txt,我会得到 E492: Not an editor command: dd - Sridhar Sarnobat
@SridharSarnobat dd 是正常模式命令,但自动化执行 Ex 命令。对于删除,您可以选择 :delete,或使用 :normal! dd;您还可以指定要删除的目标行号/范围。 (哦,只需删除整行,您不需要 Vim - sed 就可以胜任。) - Ingo Karkat
感谢您的快速回复,我已经放弃了。我发现自己并不像想象中那样熟悉vim。是的,我可以使用sed,但我正在尝试探索vim的更多功能,超越传统用法,将其用作过滤器是利用Unix哲学更多力量的一种方式。 - Sridhar Sarnobat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接