Original Question:
I am running SUNOS 4.1.3 and attempting to replace a line in a series of
documents (HTML) in several directories to add a background. I was
wondering I could replace all the files without going through the hassle
of opening eachone. I know how to use the cat and grep command to view
the line in everyfile and have it outputted to a file. I don't mind
going to every directory all that much but would like to avoid it.
Answers:
Most of the responses suggested using awk, sed, tr, or vi to perform the
replacement. Although all these commands work great for individual
files they are not capable of performing numerous files in several
directories.
The solution I used came from Dale Sears takes advantage of the find,
and sed commands while using perl.
find . -name \* -exec perl -pi.orig -e 's/oldstring/newstring/g' {} \;
Other solutions include
On Apr 10, 15:34, Michael J. Shon {*Prof Services} Sun Rochester wrote:
> Well, the quoting can be tricky, but I use this if I have a lot of
> files to make the same edit on. I almost always use a 'sed' command to
> do the editing, but you can use anything.
>
> Test before you do it by using the "-n" option; it will show you a >
"diff" output of your file and the edit that would have been made.
>
> inplace -n 'sed "s:<BODY>:<BODY BACKGROUND=\"background2.gif\">:" <
$in > $out' \
>
path/to/*.html
>
> index.html :
> 8c8
> < <BODY>
> ---
> > <BODY BACKGROUND="background2.gif" >
>
> If the quoting gets out of hand, then put the command that you want to
perform
> into a script file (I'll assume Bourne shell) and use
> inplace 'sh scriptfile < $in > $out' all/my/files/*.html
>
> usage: inplace [ -h -n -v -x ] 'command' file...
>
> perform <command> for each file ;
> intended for relatively safe in-place editing of files
>
> Command can be almost any shell command, but must be a single
> parameter to inplace .
> It will usually need to be quoted ; single quotes are easiest.
>
> In <command> you may use $in for an input file and $out for
> an output file, $d for the directory part of the input file
name,
> $b for the final part of the input file name (the basename) ,
> and $file for the original file name.
>
> References to these will be incorrect if they are not
single-quoted
> or preceded by a backslash.
>
> -h this help message
> -n show the result but do not update the file
> -v show the result
> -x turn on shell execution tracing
>
>
> [ shell-script ] :
>
> #!/bin/sh
>
> # %A% %G% %U%
>
> # facilitate in-place editing of a list of files.
> # This shell script takes a command and a sequence of filename
arguments
> # and executes the command once for each argument,
> # with the variable $in set to the name of a copy of of the filename
argument
> # and the variable $out set to a safe output file
> # If after the command, the contents of the files $in and $out differ,
> # (and $out is not empty)
> # then $out is copied back to the filename argument
> #
> # for example
> # $Prog 'sed "s/foo/bar/" $in > $out' file1 file2
> #
>
> Prog=$0
>
> usage()
> {
> cat 1>&2 << EOU
>
> usage: $Prog [ -h -n -v -x ] 'command' file...
>
> perform <command> for each file ;
> intended for relatively safe in-place editing of files
>
> Command can be almost any shell command, but must be a single
> parameter to $Prog .
> It will usually need to be quoted ; single quotes are easiest.
>
> In <command> you may use \$in for an input file and \$out for
> an output file, \$d for the directory part of the input file
name,
> \$b for the final part of the input file name (the basename) ,
> and \$file for the original file name.
>
> References to these will be incorrect if they are not
single-quoted
> or preceded by a backslash.
>
> -h this help message
> -n show the result but do not update the file
> -v show the result
> -x turn on shell execution tracing
>
>
> EOU
> }
>
> msg()
> {
> echo "$@" 1>&2
> }
>
> verbose=false
> update=true
> while getopts nhvx arg
> do
> : arg is \"$arg\"
> case "$arg" in
>
> h|\?) usage ; exit 0 ;;
> v) verbose=true ;;
> x) set -x ;;
> n) update=false ; verbose=true ;;
> esac
> done
> test $OPTIND -gt 1 && shift `expr $OPTIND - 1`
> if [ "$2" = "" ] ; then
> usage
> exit 1
> fi
>
> in=/tmp/,inpi.$$
> out=/tmp/,inpo.$$
> touch $in $out || exit 1
>
> trap "rm -f $in $out ; exit 0" 1 2 3 4 15
>
> startdir=`pwd`
>
> # the first arg is the command to execute
> c="$1"
> shift
>
> if echo "$c" | grep '$in' > /dev/null ; then
> : ok - uses the input file
> else
> msg Warning: '$in' is not used by "$c"
> fi
> if echo "$c" | grep '$out' > /dev/null ; then
> : ok - uses the input file
> else
> msg Warning: '$out' is not used by "$c"
> fi
>
>
> for file in "$@"
> do
> cd $startdir
> echo " $file" : 1>&2
> if test ! -f $file ; then
> msg $file : No such file
> continue
> fi
> ipd=`dirname $file`
> d=$ipd
> ipb=`basename $file`
> b=$ipb
> if test ! -w $file ; then
> if test -f $ipd/SCCS/s.$ipb ; then
> (
> cd $ipd
> sccs edit $ipb || exit 1
> ) || continue
> fi
> if test ! -w $file ; then
> msg $file: not writable
> continue
> fi
> fi
> chmod +w $in $out
> cp $file $in || continue
> cp /dev/null $out || exit 1
> chmod +w $in $out
> ( eval "$c" )
>
> if test -s "$out" ; then
> if cmp $in $out > /dev/null 2>&1 ; then
> msg No change to $file
> else
> $verbose && diff $file $out
> $update && cp $out $file
> fi
> else
> msg No output!
> fi
> done
>
> exit
>
> #
> #
> # ________ SCCS/s.inplace:
> # 1.4 95/10/16 11:10:41
> # added sanity check code to warn if $in and/or $out are not used
in
> # the command
> # changed echos to msg()s
> # 1.3 95/10/05 13:08:46
> # execute command in subshell so that variables are safe, user can
exit
> # 1.2 95/10/04 12:28:50
> # improved usage message
> # added $b $d $file to $in $out for ease of use
> # 1.1 95/10/03 10:49:17
> #
>-- End of excerpt from Michael J. Shon {*Prof Services} Sun Rochester
On Apr 10, 14:57, Chris Mayo wrote:
> use the sed command in a script file:
>
> #!/bin/sh
>
> for i in *.html
> do
> sed 's#old string#new string#' $i > $i.new
> done
>
> In this example, I used # for delimiter cuz you may want to use the
> slash to indicate directory...
>
>-- End of excerpt from Chris Mayo
On Apr 10, 17:59, mickey wrote:
> <in root directory>
>
> find . -name \*.html -print |
> while read name
> do
> cp $name $name.old
> sed s/<string1>/<strig2>/g $name.old $name
> echo $name
> done
>
> then verify, then do
>
> find . -name \*.html.old -exec rm {} \;
>
> depending on what <string1> and <string2> are, you may have to escape
> certain characters accordingly
mickey@intr.net
>
>-- End of excerpt from mickey
On Apr 11, 8:45, James Ashton wrote:
> This is the kind of things that shell scripts are good for. The
> following is (a completely untested) example of the kind of thing you
> might use. Put it in a file, make it executable, and run it with the
> names of the files you want to change. You should check out the man
> page on sed to see how to get it to do exactly what you want. You
need
> to ensure it doesn't perform replacements in inappropriate places so
> make sure the pattern describing the text to be replaced will only
> match the line you want.
>
> #!/bin/sh
> for i
> do
> sed 's:The text you want to replace:The replacement text:' "$i"
\
> >> "$i.new" && mv "$i.new" "$i"
> done
>-- End of excerpt from James Ashton
On Apr 10, 17:04, John Justin Hough wrote:
> Subject: Re: Text file assistance
>
> Antonio,
>
> If you know the line and it is unique enough you can use ed -
>
> find where-ever -type f -print | while read f ; do
> egrep 're-for-unique-pattern' >/dev/null 2>&1
> if [ $? -eq 0 ] ; then
> ed $f <<!
> /re-for-unique-pattern
> s/source-string/changed-string/
> w
> q
> !
> fi
> done
>-- End of excerpt from John Justin Hough
This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:10:57 CDT