在安全地避免git目录的同时递归替换字符串

时间:2016-11-12 00:39:15

标签: git awk sed find

如何在当前目录和所有子目录中用ABC替换XYZ的所有实例?

this popular question中,最佳答案指出运行

等命令是不明智的
find /home/www -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'

在包含.git目录的文件夹中,因为历史记录可能已损坏。

因此,如何在 中包含.git目录的文件夹中进行替换?这是怎么回事?:

find /home/www/ -type f -not -path .git/ -exec \
    sed -i 's/ABC/XYZ/g' {} +

2 个答案:

答案 0 :(得分:3)

您需要“修剪”.git目录。查找的-prune指令总是成功,并且作为副作用,终止目录中的搜索;并且发现or运算符是短路的,所以:

find $top -name .git -prune -o -type f -print0 | xargs -0 ...
例如

。这表示:对于每个文件,如果名称为.git -prune成功,我们就完成了(-prune确实成功了,我们不会下降进入.git)。否则,名称不是.git,因此我们执行“或”子句:如果类型为“file”,则为-print0

因此,这将打印不是.git目录的文件的所有名称,也不会打印在.git目录中。 (当然.git目录也不是文件,但我们必须测试它才能使用-prune。)

答案 1 :(得分:1)

  

在这个热门问题中,最热门的答案指出,在包含.git目录的文件夹中运行find /home/www -type f -print0 | xargs -0 sed -i 's/ABC/ABX/g'等命令是不明智的,因为历史记录可能会损坏。

它不仅仅是git目录,而是用于软件开发的任何东西。构建产品,数据库,测试的预期结果......这样的命令就是在乞求麻烦。

git grep -lIz ABC | xargs -0 sed -i 's/ABC/DEF/g'

将为您提供跟踪的文本文件,这是一个不错的开始,您也可以提供路径名模式(例如git grep foobar -- '*.[ch]'显示跟踪的.c和.h文件中的所有匹配行)