从命令行在Vim中执行命令

74
有没有一种方法可以从命令行上执行Vim指令并作用于文件? 我知道反过来是可行的,像这样:
:!python %

但是如果我想在不打开Vim的情况下:retab一个文件怎么办?例如:

> vim myfile.c
:retab | wq

这将打开myfile.c文件,将其中的制表符替换为空格,然后保存并关闭。我想以某种方式将这个序列链接成一个单一的命令。

大概会像这样:

> vim myfile.c retab | wq
3个回答

67

这个有效:

gvim -c "set et|retab|wq" foo.txt

set et (= set expandtab) 确保将tab字符替换为正确数量的空格(否则retab将无法正常工作)。

我通常不使用它,但vim -c ...也可以。

上述解决方案假定默认制表位为八个空格是合适的。如果打算使用四个空格的制表符,则使用命令序列"set ts=4|set et|retab|wq"


我尝试使用xargsfind -name \*.[ch] | xargs -n 1 vim -c“set et|retab|wq”)在多个文件上运行它,但速度非常慢。每次调用时,vim都会抱怨输入不是来自终端,并且我认为它会延迟一两秒钟以允许读取消息。另外,for循环不会影响stdin,因此速度很快:for f in $(find -name \*.[ch]); do vim -c“set et|retab|wq”$f; done。然而,这并不完美,例如带有空格或太多文件名的文件名会破坏它(因此可能vim有一个选项来抑制该警告)。 - Matthijs Kooijman

59

你有几个选项:

  • -c "commands" :将作为命令行输入的 Ex 命令播放。
    在你的例子中:vim myfile -c 'retab | wq'。这是 Firstrock 建议的方法。

  • -S "vim source file" :将提供的 vim 脚本源文件进行源
    (就像运行vim -c "source 'vim source file'"):

    如果你有一个名为script.vim的文件,内容为:

    retab
    wq
    

    那么你可以使用 vim myfile.c -s script.vim(扩展名并不重要)

  • -s“scriptin文件”:将文件的内容作为包含普通模式命令的脚本进行执行。如果你有一个包含以下内容的script.txt

    :retab
    ZZ
    

    如果你的文件以单个^M字符作为换行符(例如通过:set fileformat=mac | w保存脚本),那么你可以运行以下命令:vim myfile.c -S script.txtZZ也是退出vim并保存当前文件的另一种方式)。请注意,你还可以使用vim my_file -W script.txt记录这些脚本,但如果你使用gvim(图形用户界面),它会出现错误


1
如果你和我一样,只想执行一些命令,在某些 shell 中,你可以使用 vim -S <(echo -e "VundleInstall \n q \n q") - Minix

2

这并不是对你问题的直接回答,但如果你想用空格替换制表符(或进行任何其他正则表达式搜索/替换),针对一组文件,你可以使用原地sed搜索/替换:

sed -i 's/\t/   /g' foo1.txt foo2.txt

或者
ls *.txt | xargs sed -i 's/\t/   /g'

(在此示例中,我将每个制表符替换为三个空格。)
注意:-i标志表示原地操作。
从sed手册页面中可以看到:
   -i[SUFFIX], --in-place[=SUFFIX]

          edit files in place (makes backup if  extension
          supplied)

你是正确的——人们不应该把显微镜用作开罐器。 - oxfn
1
根据我的经验,如果文件很大(数百MB级别),而替换的数量有限,则使用sed会非常慢。@benoit建议的“vim -s <script_file>”选项速度要快得多——几秒钟的时间。在我的情况下,对于一个200MB大小、约100个替换的文件,sed花费了约3分钟的时间,而vim脚本选项仅用了约25秒的时间完成。 - Prashant

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