Vim如何在Bash中插入文本,保存并退出

3

我有多个文件需要编辑。我需要进行一些更改,比如根据模式复制某些行,然后在不同的位置插入一些文本。我计划使用vim来自动化我的任务。我已经编写了这个脚本:

gg
i
some text to add
some more text to add
<esc>
:%s/text/TEXT/g
:wq

但是它只是打开了 Vim 编辑器并将命令插入到文件中,然后我必须手动删除以下文本

<esc>
:%s/text/TEXT/g
:wq

并保存文件。

我正在调用以下命令:

vi -s vimscript mytextfile

我之前使用过vim脚本来做一些与插入文本无关的事情,比如搜索和替换,复制粘贴模式等。

4个回答

5

替代方案

除非你真的需要特殊的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可以从stdin读取命令。如果使用"- "参数,您还可以从stderr读取命令,填充新缓冲区以从stdin读取文本。

全自动化

对于涉及多个窗口的更高级处理和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.

3

:help -s命令中得知:

-s {scriptin}   The script file "scriptin" is read.  The characters in the
                file are interpreted as if you had typed them.  The same can
                be done with the command ":source! {scriptin}".  If the end
                of the file is reached before the editor exits, further
                characters are read from the keyboard.  Only works when not
                started in Ex mode, see |-s-ex|.  See also |complex-repeat|.
                {not in Vi}

可以将其视为宏。这是你的 vimscript 文件应该看起来的样子:

Osome text to add^Msome more text to add^[:%s/text/TEXT^M:wq^M

^M特殊字符是一个字面上的<CR>,可以通过<C-v><CR>获得。

^[特殊字符是一个字面上的<Esc>,可以通过<C-v><Esc>获得。


我该如何在脚本中搜索文本,比如说“/findthis”?然后我想删除第一个搜索位置之前的所有文本。 - Tem Pora

3

为什么要使用vim来自动化这种任务,而有很多命令或shell语言可以更好更有效地完成呢?你可以使用其他工具来自动化你的任务。

例如,你可以尝试使用sed:

[ ~]$ cat file
Here is a file
[ ~]$ echo "some text to add" >> file
[ ~]$ echo "some more text to add" >> file
[ ~]$ cat file
Here is a file
some text to add
some more text to add
[ ~]$ sed -i "s/text/TEXT/g" file
[ ~]$ cat file
Here is a file
some TEXT to add
some more TEXT to add

编辑:在文件顶部插入文本的方法有很多种。

使用临时文件:

 echo "some text to add" > tmp.txt
 cat file.text >> tmp.txt
 mv tmp.text file.txt

使用 sed:

sed -i "1isome text to add" file.text # or
sed -i "1s/^/some text to add\n/" file.txt

使用子shell:

echo -e "some text to add\n$(cat file.txt)" > file.txt

sed是否支持vi支持的“g”类型功能?我不知道。我更习惯于使用vi,所以感觉很自在。无论如何,还是谢谢你指出效率问题。 - Tem Pora
@TemPora 我已经编辑了我的帖子,添加了一些关于在文件顶部插入文本的提示。我猜这相当于 gg vim 命令。 - Idriss Neumann
此外,我认为在大量文件上自动化这种任务使用vim并不是一个好主意。 - Idriss Neumann

2

我发现使用标准的Vim脚本比使用正常模式脚本更自然。您可以使用以下命令调用它:

vim -c "source vimscript" mytextfile

您的vim脚本需要进行一些更新才能使用这种方法。它将类似于:

1
i
some text to add
some more text to add
.
%s/text/TEXT/g
wq

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