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

subdomainA.example.com

具有

subdomainB.example.com

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


当前回答

一个很好的oneliner作为额外的。使用git grep。

git grep -lz 'subdomainA.example.com' | xargs -0 perl -i'' -pE "s/subdomainA.example.com/subdomainB.example.com/g"

其他回答

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

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

这是我为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>
perl -p -i -e 's/oldthing/new_thingy/g' `grep -ril oldthing *`

我很惊讶我没有看到使用文件globbing的简单答案,我只使用**/package.json扫描/更新package.json文件

这是zsh下macos特有的

cd /home/www
sed -i '' -e 's/subdomainA.example.com/subdomainA.example.com/g' **/*

最简单的替换方式(所有文件、目录、递归)

find . -type f -not -path '*/\.*' -exec sed -i 's/foo/bar/g' {} +

注意:有时您可能需要忽略一些隐藏文件,例如.git,您可以使用上面的命令。

如果要包含隐藏文件,请使用,

find . -type f  -exec sed -i 's/foo/bar/g' {} +

在这两种情况下,字符串foo将被替换为新的字符串栏