我如何查找并替换每次出现的:

subdomainA.example.com

具有

subdomainB.example.com

递归地在/home/www/目录树下的每个文本文件中?


当前回答

如果您不介意将vim与grep或find工具一起使用,您可以在以下链接中跟进用户Gert给出的答案-->如何在大文件夹层次结构中进行文本替换?。

交易如下:

递归地对要在某个路径中替换的字符串执行grep,并只获取匹配文件的完整路径。(这将是$(grep”字符串“”路径名“-Rl”)。(可选)如果您想对集中目录上的这些文件进行预备份,您也可以使用以下命令:cp-iv$(grep‘string‘‘pathname‘-Rl)‘集中目录路径名‘之后,您可以在vim中按照与给定链接上提供的方案类似的方案随意编辑/替换::bufdo%s#string#replacement#gc | update

其他回答

对我来说,最容易记住的解决方案是https://stackoverflow.com/a/2113224/565525即:

sed -i '' -e 's/subdomainA/subdomainB/g' $(find /home/www/ -type f)

注意:-i“”解决了OSX问题sed:1:“…”:命令代码无效。

注意:如果要处理的文件太多,参数列表会太长。解决方法-使用上述find-exec或xargs解决方案。

对于任何使用银搜索器(ag)的人

ag SearchString -l0 | xargs -0 sed -i 's/SearchString/Replacement/g'

由于ag默认忽略git/hg/svn文件/文件夹,因此在存储库中运行是安全的。

这是我为OSX和Windows(msys2)找到的最好的全方位解决方案。应该可以使用任何可以获得gnu版本sed的东西。跳过.git目录,这样不会损坏您的校验和。

在mac上,只需先安装coreutils并确保gsed在路径中-

brew install coreutils

然后我将此函数粘贴到zshrc/bashrc->

replace-recursive() {
    hash gsed 2>/dev/null && local SED_CMD="gsed" || SED_CMD="sed"
    find . -type f -name "*.*" -not -path "*/.git/*" -print0 | xargs -0 $SED_CMD -i "s/$1/$2/g"
}

usage: replace-recursive <find> <replace>

如果您想在不完全破坏SVN存储库的情况下使用此功能,可以通过以下操作告诉“查找”忽略所有隐藏文件:

find . \( ! -regex '.*/\..*' \) -type f -print0 | xargs -0 sed -i 's/subdomainA.example.com/subdomainB.example.com/g'

这一个与git存储库兼容,而且更简单:

Linux:

git grep -l 'original_text' | xargs sed -i 's/original_text/new_text/g'

Mac:

git grep -l 'original_text' | xargs sed -i '' -e 's/original_text/new_text/g'

(感谢http://blog.jasonmeridth.com/posts/use-git-grep-to-replace-strings-in-files-in-your-git-repository/)