A while ago I sent mail about wanting to find all files that had a certain
text string in it and changing it to something else. People mentioned
that there is a system tool to do it (gnome has it too). I ran this, for
example to find all files WITH "prog" in the name, and then I did a ps
and I saw simply
find . -iname '*prog*'
then I did something similar, all file names but with "prog" in it,
and
found basically two lines (one was child process of the other, so I assume
it was a pipe or something):
find . -type f
grep -i -c prog
this does a grep for case insensitivity for "prog", so basically the
tool
uses find and grep.
I could do something like
find . -type f |
while read fil
do
sed -i 's/prog/name/g' $f # change "prog" to
"name"
done
A couple problems here. If what I am changing is the same length then it
may be ok. But consider this quick (example) C program state.c
int main( int argc, char **argv )
{
printf( "Ohio\n" );
}
if I compile it to "state" and then print it prints Ohio. If I do (on
the
compiled file state) sed -i 's/Ohio/Utah/' state then it will
print
Utah. However, if I change the length sed -i 's/Ohio/Michigan/' state
it will of course SIGSEGV because it changed some of the object code.
(Actually even doing the same length can be dangerous).
What I want to do is either provide another option to the find (which I
can'e seem to find), or pipe the files it finds to something like
"file"
to get only ASCII files (non-object code). However, I am not sure how
to do this. On most files, the "file" command will return something
with
"text" in it, but not all files. For instance, sometimes it returns
"application" or "shell script" but it is still OK to do the
sed on these.
Is there some easy way to take a file name and determine whether sed -i
can safely be done on it (i.e., it is ASCII and not some sort of binary
file)?
Tony