400
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
|
3807
ed > sed
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
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, | <<Anchor(faq21)>> == How can I replace a string with another string in all files? == {{{ed}}} is the standard UNIX command-based editor. Here's three commonly-used syntaxes for replacing the string `olddomain.com` by the string `newdomain.com` in a file named `file`. All three commands do the same although the last two incur the minor additional overhead of a subshell. {{{ # ed -s file <<< $'s/olddomain\.com/newdomain.com/g\nw' # printf '%s\n' 's/olddomain\.com/newdomain.com/g' w | ed -s file # printf 's/olddomain\.com/newdomain.com/g\nw' | ed -s file }}} To replace a string in all files of the current directory: {{{ for file in ./*; do ed <<< $'s/old/new/g\nw' "$file" done }}} {{{sed}}} is a '''Stream EDitor''', not a '''file'' editor. Nevertheless, people everywhere tend to abuse it for trying to edit files. It doesn't edit files. GNU's `sed` (and some BSD `sed`'s) have a `-i` option that makes a copy and replaces the original file with the copy. An expensive operation, but if you enjoy unportable code, I/O overhead and bad side effects (such as destroying symlinks), this would be an option: {{{ sed -i 's/old/new/g' ./* # GNU sed -i '' 's/old/new/g' ./* # BSD }}} Those of you who have perl 5 can accomplish the same thing using this code: {{{ perl -pi -e 's/old/new/g' ./* }}} Recursively using find: {{{ find . -type f -exec 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 -exec 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 0x01) * 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 |
Line 3: | Line 94: |
CategoryCategory | CategoryShell |
How can I replace a string with another string in all files?
ed is the standard UNIX command-based editor. Here's three commonly-used syntaxes for replacing the string olddomain.com by the string newdomain.com in a file named file. All three commands do the same although the last two incur the minor additional overhead of a subshell.
# ed -s file <<< $'s/olddomain\.com/newdomain.com/g\nw' # printf '%s\n' 's/olddomain\.com/newdomain.com/g' w | ed -s file # printf 's/olddomain\.com/newdomain.com/g\nw' | ed -s file
To replace a string in all files of the current directory:
for file in ./*; do ed <<< $'s/old/new/g\nw' "$file" done
sed is a Stream EDitor, not a file editor. Nevertheless, people everywhere tend to abuse it for trying to edit files. It doesn't edit files. GNU's sed (and some BSD sed's) have a -i option that makes a copy and replaces the original file with the copy. An expensive operation, but if you enjoy unportable code, I/O overhead and bad side effects (such as destroying symlinks), this would be an option: Those of you who have perl 5 can accomplish the same thing using this code: Recursively using find: If you want to delete lines instead of making substitutions: To replace for example all "unsigned" with "unsigned long", if it is not "unsigned int" or "unsigned long" ...: Finally, for those of you with 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: Many optimizations are possible: use another sed separator character than '|', e.g. ^A (ASCII 0x01) the 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 sed -i 's/old/new/g' ./* # GNU
sed -i '' 's/old/new/g' ./* # BSD
perl -pi -e 's/old/new/g' ./*
find . -type f -exec perl -pi -e 's/old/new/g' {} +
perl -ni -e 'print unless /foo/' ./*
# Deletes any line containing the perl regex foo
find . -type f -exec perl -i.bak -pne \
's/\bunsigned\b(?!\s+(int|short|long|char))/unsigned long/g' {} +
#!/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
find . -type f -name '*.html' -exec chtext {} \;