How to do a recursive find/replace of a string with awk or sed?

后端 未结 30 1581
盖世英雄少女心
盖世英雄少女心 2020-11-22 06:39

How do I find and replace every occurrence of:

subdomainA.example.com

with

subdomainB.example.com

in eve

相关标签:
30条回答
  • 2020-11-22 07:17
    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 tells find to print each of the results separated by a null character, rather than a new line. In the unlikely event that your directory has files with newlines in the names, this still lets xargs work on the correct filenames.

    \( -type d -name .git -prune \) is an expression which completely skips over all directories named .git. You could easily expand it, if you use SVN or have other folders you want to preserve -- just match against more names. It's roughly equivalent to -not -path .git, but more efficient, because rather than checking every file in the directory, it skips it entirely. The -o after it is required because of how -prune actually works.

    For more information, see man find.

    0 讨论(0)
  • 2020-11-22 07:19

    Simplest way to replace (all files, directory, recursive)

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

    Note: Sometimes you might need to ignore some hidden files i.e. .git, you can use above command.

    If you want to include hidden files use,

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

    In both case the string foo will be replaced with new string bar

    0 讨论(0)
  • 2020-11-22 07:20

    To cut down on files to recursively sed through, you could grep for your string instance:

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

    If you run man grep you'll notice you can also define an --exlude-dir="*.git" flag if you want to omit searching through .git directories, avoiding git index issues as others have politely pointed out.

    Leading you to:

    grep -rl --exclude-dir="*.git" <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
    
    0 讨论(0)
  • 2020-11-22 07:20

    I just needed this and was not happy with the speed of the available examples. So I came up with my own:

    cd /var/www && ack-grep -l --print0 subdomainA.example.com | xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'
    

    Ack-grep is very efficient on finding relevant files. This command replaced ~145 000 files with a breeze whereas others took so long I couldn't wait until they finish.

    0 讨论(0)
  • 2020-11-22 07:24

    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
    0 讨论(0)
  • 2020-11-22 07:26

    All the tricks are almost the same, but I like this one:

    find <mydir> -type f -exec sed -i 's/<string1>/<string2>/g' {} +
    
    • find <mydir>: look up in the directory.

    • -type f:

      File is of type: regular file

    • -exec command {} +:

      This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invocations of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of `{}' is allowed within the command. The command is executed in the starting directory.

    0 讨论(0)
提交回复
热议问题