Another question about find. I looked at the gnome tool and tried to simulate what it is doing. I can't use it directly because it won't do sed. Basically I want to find all files with a string (except binary) and change it. let STR be the string I am looking for. NEW is new string. I am doing TFIL=/usr/tmp/dummy$$.txt find . -type f | while read fil do grep "$STR" $fil > $TFIL [ $? -eq 0 ] || continue ## does not match if [ "$(cat $TFIL)" = "Binary file $fil matches" ] then continue # Don't operate on binary files fi sed -i "s/$STR/$NEW/g" $fil done (I will have to do something with sed in case there is "/" in the string) Problem is, the grep redefines my stdin so it no longer comes from the list of files that "find" found, and it then terminates after finding the first file. Anyway to "push" stdin on the stack or something before the grep, and "pop" it again afterwards, so it goes back to the list of files found?
On Wed, Oct 8, 2008 at 9:49 PM, <tony.chamberlain at lemko.com> wrote:> > Basically I want to find all files with a string (except binary) > and change it. let STR be the string I am looking for. NEW is newstring. Hmm, why not ditch find entirely, and just use grep? Something like: TFIL=/usr/tmp/dummy$$.txt grep -Ilr "$STR" * > $TFIL for fil in $( cat $TFIL); do sed -i "s/$STR/$NEW/g" $fil done Man grep says: "-I Process a binary file as if it did not contain matching data". Also -l gives you the filename and relative path. If $STR contains "/"s then you could use # instead. sed -i "s#$STR#$NEW#g" $fil I dont know how much the searched for string would change, but you could test if it contained "/" and then use sed with "#" instead. Also you might want to use "sed -ibak ..." instead since this will backup the unchanged file to filename.bak, should your substitution go awry. The letters after "i" specify the extension you want to use. Eric Sisolak -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.centos.org/pipermail/centos/attachments/20081010/b7524713/attachment-0003.html>
On Fri, Oct 10, 2008 at 7:19 AM, Eric Sisolak <haldir.junk at gmail.com> wrote:> On Wed, Oct 8, 2008 at 9:49 PM, <tony.chamberlain at lemko.com> wrote: >> >> Basically I want to find all files with a string (except binary) >> and change it. let STR be the string I am looking for. NEW is new >> string. > > Hmm, why not ditch find entirely, and just use grep? Something like: > > TFIL=/usr/tmp/dummy$$.txt > > grep -Ilr "$STR" * > $TFIL > > for fil in $( cat $TFIL); do > sed -i "s/$STR/$NEW/g" $fil > done >That should work, but unless you actually need to see the file list, you can do this in one command: for fil in `grep -Ilr "$STR" *`; do sed -i "s/$STR/$NEW/g" $fil; done If you really need the file list separately, you can use `grep -Ilr "$STR" * | tee $TFIL` to get the same effect. Note that this will not necessarily work with specific sets of files (as opposed to '*'). mhr