How to do a recursive find/replace of a string wit

2018-12-31 14:41发布

How do I find and replace every occurrence of:

subdomainA.example.com

with

subdomainB.example.com

in every text file under the /home/www/ directory tree recursively?

30条回答
余生无你
2楼-- · 2018-12-31 15:22

Note: Do not run this command on a folder including a git repo - changes to .git could corrupt your git index.

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

Compared to other answers here, this is simpler than most and uses sed instead of perl, which is what the original question asked for.

查看更多
步步皆殇っ
3楼-- · 2018-12-31 15:22
perl -p -i -e 's/oldthing/new_thingy/g' `grep -ril oldthing *`
查看更多
爱死公子算了
4楼-- · 2018-12-31 15:23

If you do not mind using vim together with grep or find tools, you could follow up the answer given by user Gert in this link --> How to do a text replacement in a big folder hierarchy?.

Here's the deal:

  • recursively grep for the string that you want to replace in a certain path, and take only the complete path of the matching file. (that would be the $(grep 'string' 'pathname' -Rl).

  • (optional) if you want to make a pre-backup of those files on centralized directory maybe you can use this also: cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'

  • after that you can edit/replace at will in vim following a scheme similar to the one provided on the link given:

    • :bufdo %s#string#replacement#gc | update
查看更多
无与为乐者.
5楼-- · 2018-12-31 15:25

This is the best all around solution I've found for OSX and Windows (msys2). Should work with anything that can get the gnu version of sed. Skips the .git directories so it won't corrupt your checksums.

On mac, just install coreutils first and ensure gsed is in the path -

brew install coreutils

Then I stick this function in my 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>
查看更多
浮光初槿花落
6楼-- · 2018-12-31 15:26

The simplest way for me is

grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'
查看更多
永恒的永恒
7楼-- · 2018-12-31 15:26

For Qshell (qsh) on IBMi, not bash as tagged by OP.

Limitations of qsh commands:

  • find does not have the -print0 option
  • xargs does not have -0 option
  • sed does not have -i option

Thus the solution in 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

Caveats:

  • Solution excludes error handling
  • Not Bash as tagged by OP
查看更多
登录 后发表回答