正确搜索和替换源代码的最简单方法

时间:2011-12-23 02:58:26

标签: bash shell search replace sed

每当这种情况出现时,大约每隔几个月出现一次,我最终会花费太长时间试图找出一个完全符合我想要的bash脚本。我很确定我想要的是类似于其他人想要的东西,但是当我进行快速搜索时,在线可用的脚本往往过于简单而且不做这些事情(我自己的bash脚本技能不好)足以弄明白了):

  1. 需要递归(遍历整个文件夹树)
  2. 必须允许我选择文件类型(例如“* .js”),因为有时文件夹树包含不应搜索的二进制文件和其他文件类型
  3. 它应该就地替换文本,编辑现有文件
  4. 它不应该导致源代码控制(git,svn)认为文件已被修改,除非它实际上已被修改(我不知道为什么,但sed似乎这样做)
  5. 应该允许正则表达式
  6. SIMPLEST 实现此目的的方法是什么?我的意思是,我可以在python中编写一个脚本,它只会是几行,但我觉得这应该很容易在shell中完成。

7 个答案:

答案 0 :(得分:3)

我通常做这样的事情:

find . -name '*.hpp' -o -name '*.cpp' | xargs grep -l StuffToEdit
然后,我看看我是否收到了感兴趣的文件。如果是的话,我会加入管道:

| xargs sed -i 's@StuffToEdit@NewStuffInstead@g'

让我们扯掉。

如果sed使你的VCS认为文件被更改,那么你应该看看差异。也许你的差异中有空格被关闭,但那就是变化(行尾等)?

我确信有人会来指出我对xargs的一个或两个使用没有必要,但对于一次性工作,这没关系。无论如何,我更喜欢这些多程序管道,因为我可以轻松地禁用或交换某些过滤器,如果结果最初不正确,则检查其余的结果。

答案 1 :(得分:3)

这应符合您的要求:

find /path/to/dir/ -type f -name "*.txt" -exec sed -i 's/substitution/replacement/g' {} \;
|                 | |                     |    |                                   |     
 -----------------   ---------------------      -----------------------------------   
         |                     |                                 |                      
This will do the     This will allow you        This will do your substitution. -i       
search of files      to specify filename        option will do it inline. You can     
recursively for      You can also use           use -r option to use Extended Regex  
the supplied path.   -regex option for          as sed's native support is BRE.       
                      better search. -type
                     is to limit your search. 
                     i.e f for regular files,
                     d for directories, l for 
                     symbolic links etc

答案 2 :(得分:2)

find /path/to/source/tree -name \*.js -exec sed -i -e'edit stuff here' {} \;

答案 3 :(得分:0)

嗯,你可以通过跟随剧本来实现。

find . -name "*.js" | grep -v "\.svn" |xargs sed -i -e "s/src/dst/g"
  1. cd你的项目目录
  2. 找到您的目标文件类型
  3. 过滤掉svn
  4. 将每个文件放入sed命令。
  5. 在上面的sed脚本中,“src”和“dst”支持regx。
  6. 希望这会对你有所帮助:)。

答案 4 :(得分:0)

find . -name "*.cpp" -o -name "*.hpp"|xargs perl -pi -e 's/search/replace/g'

答案 5 :(得分:0)

您可以使用ex命令(Vim的一部分,与vim -E相同),例如

ex "+bufdo! %s/foo/bar/g" -scxa **/*.js

如果您的shell支持a new globbing option(由shopt -s globstar启用),则**将以递归方式运行。

说明:

  • bufdo! - 从参数中强制调用所有文件的下一个命令;
  • %s/foo/bar/g - s ubstitute foobar g lobally(% - 整个文件,{{ 1}} - 多个实例);
  • g - s ilently exe c ute save and quit(x) a ll;

-scxa相比,使用ex具有以下优势:

  • sed S tream ED itor,而不是文件编辑器。 BashFAQ/021
  • 它不会将符号链接销毁为sed is doing this by default
  • Ex语法更高级(因为它使用Vim命令)并且它更可靠(例如sed中的-i是非标准的FreeBSD扩展,可能在其他操作系统上不可用)。

答案 6 :(得分:0)

如果您正在处理 git 存储库,此脚本可让您搜索替换 perl 正则表达式模式:https://github.com/Chiel92/replac

vecs[:,2]