从 bash 脚本中调用 vim 的搜索和替换函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6945558/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling search and replace functions for vim from within a bash script
提问by Sriram
I have a number (> 100) of files that I want to process using vim. The text of a sample file contains the following (just a sample):
我有很多(> 100 个)文件要使用 vim 处理。示例文件的文本包含以下内容(只是一个示例):
xyz.csv /home/user/mydocs/abc.txt
/home/user/waves/wav.wav , user_wav.wav
I want this to be replaced by:
我希望将其替换为:
xyz.csv /var/lib/mydir/abc.txt
/var/sounds/wav.wav , wav.wav
In each of the files, the changes I need to make are the same. My question is:
在每个文件中,我需要进行的更改都是相同的。我的问题是:
Can I use the search and replace function within
vimby calling it from within a bash script?If so, how do I go about it?
我可以
vim通过从 bash 脚本中调用来使用其中的搜索和替换功能吗?如果是这样,我该怎么做?
P.S: I have searched SO for some replies and found some answers like exscripts etc. I want to know how I can call an exscript from within a bashscript.
PS:我搜索了一些回复并找到了一些答案,如ex脚本等。我想知道如何ex从bash脚本中调用脚本。
回答by mattr-
While vim is quite powerful, this is not something I would normally use vim for. It can be done using a combination of common command line utilities instead.
虽然 vim 非常强大,但这不是我通常会使用 vim 的东西。可以使用通用命令行实用程序的组合来完成。
I've assumed that the blank line in your example above is actually blank and does not contain spaces or any other whitespace characters. You can use the following to do what you want.
我假设上面示例中的空白行实际上是空白的,并且不包含空格或任何其他空白字符。您可以使用以下内容来执行您想要的操作。
sed -e "s,/home/user/mydocs,/var/lib/mydir," -e "s,/home/user/waves,/var/sounds," -e "/^$/d" file1
You can use that command together with findand a for loop to do this for a bunch of files:
您可以将该命令与findfor 循环一起使用来为一堆文件执行此操作:
for file in `find . -maxdepth 1 -type f`
do
sed -e "s,/home/user/mydocs,/var/lib/mydir," -e "s,/home/user/waves,/var/sounds," -e "/^$/d" $file
done
In the for loop, the find command above limits the output to all files in the current directory (including dot files), assigning each line from the output of find to the filevariable and then running the sedcommand posted earlier to transform the file the way you want it to be transformed.
在 for 循环中,上面的 find 命令将输出限制为当前目录中的所有文件(包括点文件),将 find 输出中的每一行分配给file变量,然后运行sed之前发布的命令以按照您的方式转换文件想要它被改造。
回答by glenn Hymanman
This is how you'd invoke an edscript from bash:
这是ed从 bash调用脚本的方式:
ed filename <<END
/^$/d
%s|/home/user/mydocs|/var/lib/mydir|
%s|/home/user/waves|/var/sounds|
%s|, user_|, |
w
q
END
回答by Zsolt Botykai
To answer with vim, you can do
要回答vim,你可以这样做
vim -e 'bufdo!%s:\(xyz.csv \)/home/user/mydocs/\(abc.txt\n\)\n.*:/var/lib/mydir//var/sounds/wav.wav , wav.wav:' -e 'xa' FILES
Note, I had assumed, that the second line is statically replaced, as it had looked like in the question.
注意,我假设第二行被静态替换,就像问题中的样子。
If you don't like writing long lines in your script, you can create a file like:
如果您不喜欢在脚本中写长行,您可以创建一个文件,如:
s/FOO/BAR/
" several replacement and other commands
w " write the file
bd " if you want to
Then do:
然后做:
vim -e "buffdo!source /your_scriptfile" -e "x" FILES
HTH
HTH
回答by ib.
If all the editing consists in series of substitutions, the most idiomatic way of accomplishing it with Vim would be the following.
如果所有的编辑都包含在一系列替换中,那么使用 Vim 完成它的最惯用的方法如下。
Open all the target files at once.
vim *.txtRun the substitution commands on loaded files.
:argdo %s#/home/user/mydocs#/var/lib/mydir# :argdo %s#/home/user/waves#/var/sounds# :argdo %s/, \zsuser_// :" etcOr, in one command:
:argdo %s#/home/user/mydocs#/var/lib/mydir# | %s#/home/user/waves#/var/sounds# | %s/, \zsuser_//If changes are correctly made, save them.
:wall
一次打开所有目标文件。
vim *.txt对加载的文件运行替换命令。
:argdo %s#/home/user/mydocs#/var/lib/mydir# :argdo %s#/home/user/waves#/var/sounds# :argdo %s/, \zsuser_// :" etc或者,在一个命令中:
:argdo %s#/home/user/mydocs#/var/lib/mydir# | %s#/home/user/waves#/var/sounds# | %s/, \zsuser_//如果更改正确,请保存。
:wall
If the editing one wants to automate could not be expressed only in substitutions, record a macro and run the same way as above:
如果想要自动化的编辑不能仅用替换来表达,请录制一个宏并以与上述相同的方式运行:
:argdo norm!@z
(here zis the name of a macro).
(这里z是宏的名称)。
Lastly, if the editing should be performed from time to time and needs to be stored as a script, try using the approach described in the answerto similar question.
回答by Dwight Spencer
Answer
回答
While most vim users would be aware of the % motion command for executing inclusive commands on the whole document in the current buffer. Most modern versions of vim (ie 6.x+) support actions on regex searches for exclusive actions like so:
虽然大多数 vim 用户会知道 % motion 命令用于在当前缓冲区中的整个文档上执行包含命令。大多数现代版本的 vim(即 6.x+)支持对 regex 搜索的操作,例如这样的独占操作:
:/regex/substitute/match/replace/ # as vim command line
+"/reges/s/match/replace" # as bash cli parameter
This breaks down into vim doing the following,
这分解为 vim 执行以下操作,
- search for regex and put the cursor at start of found point
- call internal substitute function (see :help s or :help substitute) [ could be other commands ]
- match string with regex for substitution
- replace with new string value
- 搜索正则表达式并将光标放在找到点的开头
- 调用内部替代函数(参见 :help s 或 :help 替代)[可以是其他命令]
- 将字符串与正则表达式匹配以进行替换
- 替换为新的字符串值
Effectively it operates the same as the :global command.
实际上,它的操作与 :global 命令相同。
Notes
笔记
Command after regex search can be any command, including '!"shell command"' filter commands.
regex 搜索后的命令可以是任何命令,包括 '!"shell command"' 过滤命令。
Reference Help
参考帮助
- :help global
- :help substitute
- :help filter
- :帮助全球
- :help 替代
- :帮助过滤器

