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

subdomainA.example.com

具有

subdomainB.example.com

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


当前回答

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

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

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

其他回答

注意:不要在包含git repo的文件夹上运行此命令-对.git的更改可能会损坏git索引。

find /home/www/ -type f -exec \
    sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

与这里的其他答案相比,这比大多数答案都简单,并且使用sed而不是perl,这就是最初的问题所要求的。

find /home/www/ -type f -exec perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

find/home/www/-type f将列出/home/ww/(及其子目录)中的所有文件。“-exec”标志告诉find对找到的每个文件运行以下命令。

perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

是在文件上运行的命令(一次运行多个)。{}被文件名替换。告诉find为多个文件名构建一个命令。

根据查找手册页:“命令行的构建方式与xargs构建其命令行。"

因此,不使用xargs-0或-print0就可以实现目标(并处理包含空格的文件名)。

grep-lr'submainA.example.com'|读取文件时;do sed-i“s/submainA.example.com/submainB.example.com/g”“$file”;完成

我想大多数人都不知道他们可以将某些内容导入“while read file”,这样可以避免那些讨厌的-print0参数,同时在文件名中预设空格。

在sed之前进一步添加一个echo,可以让您在实际执行之前查看哪些文件将发生更改。

对于IBMi上的Qshell(qsh),不是OP标记的bash。

qsh命令的限制:

find没有-print0选项xargs没有-0选项sed没有-i选项

因此,qsh中的解决方案:

    PATH='your/path/here'
    SEARCH=\'subdomainA.example.com\'
    REPLACE=\'subdomainB.example.com\'

    for file in $( find ${PATH} -P -type f ); do

            TEMP_FILE=${file}.${RANDOM}.temp_file

            if [ ! -e ${TEMP_FILE} ]; then
                    touch -C 819 ${TEMP_FILE}

                    sed -e 's/'$SEARCH'/'$REPLACE'/g' \
                    < ${file} > ${TEMP_FILE}

                    mv ${TEMP_FILE} ${file}
            fi
    done

注意事项:

解决方案不包括错误处理不是OP标记的Bash

这是我为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>