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

subdomainA.example.com

具有

subdomainB.example.com

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


当前回答

find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'

-print0告诉find打印由空字符分隔的每个结果,而不是新行。如果您的目录中包含名称中带有换行符的文件,这是不太可能的,那么xargs仍然可以使用正确的文件名。

\(-type d-name.git-prenne\)是一个表达式,它完全跳过名为.git的所有目录。如果您使用SVN或有其他要保留的文件夹,则可以轻松展开它,只需匹配更多名称即可。它大致相当于-not-path.git,但效率更高,因为它不检查目录中的每个文件,而是完全跳过它。后面的-o是必需的,因为-prime实际上是如何工作的。

有关更多信息,请参阅man find。

其他回答

如果您需要排除目录(--exclude-dir=..folder),并且文件名可能带有空格(通过对grep-Z和xargs-0使用0Byte来解决),这是一种直接的方法

grep -rlZ oldtext . --exclude-dir=.folder | xargs -0 sed -i 's/oldtext/newtext/g'

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

要减少要递归遍历的文件,可以对字符串实例进行grep:

grep -rl <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g

如果运行man grep,您会注意到,如果您想省略对.git目录的搜索,还可以定义一个--exlude dir=“*.git”标志,从而避免了其他人礼貌地指出的git索引问题。

引导您:

grep -rl --exclude-dir="*.git" <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g

对我来说最简单的方法是

grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'