我需要根据内容使用vim批量编辑一堆文件。最简单的例子是,我想对文件执行一系列让我们说的替换,但前提是文件的第一行与某个模式匹配。
我正在尝试这样做:
vim -e -s $file < changes.vim
我应该补充一点,我无法访问像sed和awk这样的工具,并希望在vim中执行整个操作。
答案 0 :(得分:1)
我建议您找到所需的文件列表,并将该列表传递到您想要的命令中。为此,awk
和xargs
的组合似乎很有用。你可以做一些聪明的短暂的事情......
awk 'FNR>1 {nextfile} /pattern/ { print FILENAME ; nextfile }' filePattern | xargs -I{} vim -e -s {} < changes.vim
在上文中,filePattern
提供了您想要的所有文件(可能是*.c
),/pattern/
是您要查找的匹配项的正则表达式。 xargs
将“一次输出一个”并将其替换为我放置{}
的地方的以下命令。
我想给this link一个小费,我找到了这个答案的灵感。
编辑 - 在我发布此消息后,您说您需要一个“仅限vim”的解决方案。这是......
步骤1:在开头创建一个conditionalEdits.vim
文件,其中包含以下行:
let line_num = search('searchExpression') " any regex
if line_num == 1 " first line matched
center " put your editing commands here...
update " save changes
endif
quit
当然,您需要将所有编辑命令放在if
语句中,而不是仅仅将第一行居中。
现在,您使用
执行此命令vim -c '/path/to/my/conditionalEdits.vim' -s filePattern
其中filePattern
匹配您可能感兴趣的所有文件(但在您查看内部第1行后,您肯定会知道...)
显然,您可以通过常规方式浏览文件,并查找匹配/模式等内容 - 但这是基本想法。
有用的链接:http://www.ibm.com/developerworks/library/l-vim-script-1/ 和http://learnvimscriptthehardway.stevelosh.com
我高度建议您在单独的目录中执行此操作,首先使用少量文件的副本,以确保实际执行您认为的操作。我不想对一堆被覆盖的文件负责(你做备份,对吗?)
答案 1 :(得分:1)
你可以循环遍历所有文件,如果找到模式,打开vim。一旦根据您的需要进行修改并关闭,下一个将打开。
#!/usr/bin/env bash
for file in *; do
if [[ "$(sed '1q' ${file})" == "pattern" ]]; then
vim ${file}
fi
done
答案 2 :(得分:0)
在Vim中,您可以通过:vimgrep
确定匹配的文件;要检查第一行中的匹配项,\%l
原子很方便:
:vimgrep /\%1lcertain pattern/ {file-glob}
然后,您可以使用:cfnext
遍历所有匹配项,或使用here中的:QFDo
命令。
您可以通过vim -c {cmd} -c {cmd} ...
或单独的脚本传递这些命令,如您在问题中所述。