Differences between revisions 13 and 14
Revision 13 as of 2008-11-10 02:15:28
Size: 3348
Editor: GreyCat
Comment:
Revision 14 as of 2008-11-18 09:46:23
Size: 400
Editor: cpe-071-076-252-242
Comment: Wery well! However, as you say, the pit lane signals are a very vital part of this activity which not many people like to do 1940s style kitchen appliances I've just been sitting around waiting for so
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
[[Anchor(faq21)]]
== How can I replace a string with another string in all files? ==
{{{sed}}} is a good command to replace strings, e.g.

{{{
    sed 's/olddomain\.com/newdomain.com/g' input > output
}}}

To replace a string in all files of the current directory:

{{{
    for i in *; do
        sed 's/old/new/g' "$i" > atempfile && mv atempfile "$i"
    done
}}}

GNU sed 4.x has a special {{{-i}}} flag which makes the loop and temp file unnecessary:

{{{
      sed -i 's/old/new/g' *
}}}

On some (but not all) BSD systems, sed has a {{{-i}}} flag as well, but it takes a mandatory argument. The above example then becomes

{{{
      sed -i '' 's/old/new/g' *
}}}

which in turn does not work with GNU sed. Effectively, whenever portability matters, {{{sed -i}}} should be avoided.

Those of you who have perl 5 can accomplish the same thing using this code:

{{{
    perl -pi -e 's/old/new/g' *
}}}

Recursively (requires GNU or BSD {{{find}}}):

{{{
    find . -type f -print0 | xargs -0 perl -pi -e 's/old/new/g'
}}}

If you want to delete lines instead of making substitutions:

{{{
    perl -ni -e 'print unless /foo/' *
    # Deletes any line containing the perl regex foo
}}}

To replace for example all "unsigned" with "unsigned long", if it is not "unsigned int" or "unsigned long" ...:

{{{
    find . -type f -print0 | xargs -0 perl -i.bak -pne \
 's/\bunsigned\b(?!\s+(int|short|long|char))/unsigned long/g'
}}}

Finally, for those of you with ''none'' of the useful things above, here's a script that may be useful:

{{{
    #!/bin/sh
    # chtext - change text in several files

    # neither string may contain '|' unquoted
    old='olddomain\.com'
    new='newdomain\.com'

    # if no files were specified on the command line, use all files:
    [ $# -lt 1 ] && set -- *

    for file
    do
        [ -f "$file" ] || continue # do not process e.g. directories
        [ -r "$file" ] || continue # cannot read file - ignore it
        # Replace string, write output to temporary file. Terminate script in case of errors
        sed "s|$old|$new|g" "$file" > "$file"-new || exit
        # If the file has changed, overwrite original file. Otherwise remove copy
        if cmp "$file" "$file"-new >/dev/null 2>&1
        then rm "$file"-new # file has not changed
        else mv "$file"-new "$file" # file has changed: overwrite original file
        fi
    done
}}}

If the code above is put into a script file (e.g. {{{chtext}}}), the resulting script can be used to change a text e.g. in all HTML files of the current and all subdirectories:

{{{
    find . -type f -name '*.html' -exec chtext {} \;
}}}

Many optimizations are possible:
 * use another {{{sed}}} separator character than '|', e.g. ^A (ASCII 1)
 * the [:UsingFind:find] command above could use either {{{xargs}}} or the built-in {{{xargs}}} of POSIX find

Note: {{{set -- *}}} in the code above is safe with respect to files whose names contain spaces. The expansion of * by {{{set}}} is the same as the expansion done by {{{for}}}, and filenames will be preserved properly as individual parameters, and not broken into words on whitespace.

A more sophisticated example of {{{chtext}}} is here: http://www.shelldorado.com/scripts/cmds/chtext
Wery well! However, as you say, the pit lane signals are a very vital part of this activity which not many people like to do 1940s style kitchen appliances I've just been sitting around waiting for something to happen. http://ketchup85.free.bg/recipef82.html visine cocktail count, http://fairisle58.free.bg/recipeb12.html mid-states supply kitchen design wi, Best regards,
----
CategoryCategory

Wery well! However, as you say, the pit lane signals are a very vital part of this activity which not many people like to do 1940s style kitchen appliances I've just been sitting around waiting for something to happen. http://ketchup85.free.bg/recipef82.html visine cocktail count, http://fairisle58.free.bg/recipeb12.html mid-states supply kitchen design wi, Best regards,


CategoryCategory

BashFAQ/021 (last edited 2022-11-03 23:42:27 by GreyCat)