How to run a stream based command in place on a file
Daniel Bye
freebsd at slightlystrange.org
Mon Oct 18 07:04:14 PDT 2004
On Mon, 18 October, 2004 2:34 pm, Richard Bradley said:
> Hi,
>
> I want to run stream based commands like `sed` and `tr` on the contents
> of a file, and save the results to the same file.
>
> Obviously I can do this with a temporary file:
>
> $sed s/dog/cat/ myanimals.txt > tmp.txt
> $mv tmp.txt myanimals.txt
>
> But is there any way I can do this with a single command?
>
> My first guess would be a "buffer" command that reads a file into memory
> (or into a temp file) then pipes it to stdout, e.g.
>
> $cat myanimals.txt | buffer | sed s/dog/cat/ > myanimals.txt
>
> But there isn't one which, in my experience of BSD, means it either
> wouldn't work or there is a better way to do it :-)
>
> Having read through the Bash manual and run some experiments, it seems
> that the ">" operator truncates an output file to zero length before any
> commands are run.
>
> So my missing command becomes:
>
> $cat myanimals.txt | sed s/dog/cat | bufferedwrite myanimals.txt
>
> I can't find anything like this anywhere -- any ideas what the "proper"
> way to do this is?
>
> Thanks in advance,
One way to do it, which is detailed in the O'Reilly sed & awk book[1], is
to write a thin wrapper. It needs to do the edit, save it to a temp file,
and then copy the temp file over the original.
Here is the script printed in the book (available by public ftp from
ftp.oreilly.com/published/oreilly/nutshell/sedawk_2/progs.tar.gz)
--------[ script start ]--------
#! /bin/sh
for x
do
echo "editing $x: \c"
if test "$x" = sedscr; then
echo "not editing sedscript!"
elif test -s $x; then
sed -f sedscr $x > /tmp/$x$$
if test -s /tmp/$x$$
then
if cmp -s $x /tmp/$x$$
then
echo "file not changed: \c"
else
mv $x $x.bak # save original, just in case
cp /tmp/$x$$ $x
fi
echo "done"
else
echo "Sed produced an empty file\c"
echo " - check your sedscript."
fi
rm -f /tmp/$x$$
else
echo "original file is empty."
fi
done
echo "all done"
--------[ script end ]--------
To use it, put your sed commands in a file called sedscr in the directory
containing the files to edit. Then run the command, passing it the names
of the files you want it to edit on the command line.
HTH
Dan
[1] sed & awk, 2nd edition; Dale Dougherty and Arnold Robbins; O'Reilly &
Associates, 1997.
--
Daniel Bye
PGP Key: ftp://ftp.slightlystrange.org/pgpkey/dan.asc
PGP Key fingerprint: 3B9D 8BBB EB03 BA83 5DB4 3B88 86FC F03A 90A1 BE8F
_
ASCII ribbon campaign ( )
- against HTML, vCards and X
- proprietary attachments in e-mail / \
More information about the freebsd-questions
mailing list