I have encountered some malware on my Linux server, and am trying to remove it from many php files.

I've tried endlessly with grep | sed and grep | tr and couldn't even erase a simple text string, getting different errors.

When trying:

grep -l '@error' * | xargs -0 sed -i 's/error/nothing/g'   

I receive an error message:

can't read filename.php

Using Terminal on Mac - maybe it's an OSX syntax problem?

My final task is to delete a long string of code from all the files - one that includes some $,!,?,<,>,\," symbols - will I need to backslash them?

  • 2
    It is generally much safer to restore from backup or from your source control repository. You don't have those available?
    – Mat
    Commented Apr 6, 2012 at 8:42
  • @Mat - thanks, but it's too many backups to run, I also have the specific code I'm need to remove.
    – Nona Man
    Commented Apr 6, 2012 at 9:04
  • possible duplicate of How to search and replace text in all php-files in a directory and it's subdirectories
    – sr_
    Commented Apr 6, 2012 at 10:29
  • 3
    Why make backups if you can't / won't use them? Better rethink your backup and restore strategies. Best practice is a full restore when a server was compromised. Also, backups are a perfect way to find out what's changed since a previous date.
    – jippie
    Commented Apr 6, 2012 at 11:33

2 Answers 2


You should restore from backup or source control as @Mat suggested because otherwise you cannot be 100% sure you cleaned up everything.

The problem with your command is the -0 flag for xargs, because that way xargs is expecting null-terminated arguments, which does not work with the output of grep -l. Just drop the -0 and it will work, as long as the file names don't have white spaces in them.

grep -l '@error' * | xargs sed -i 's/error/nothing/g'
  • Thanks. This works - the '-0' was the catch here. BTW - I am trying to save a log file with the list of files in which the replacement was made. Any tips on how to do that? When I save the grep results to a file they are not piped to the xargs. Thank you Janos and community!
    – Nona Man
    Commented Apr 7, 2012 at 7:13
  • 1
    Sure!grep -l '@error' * | tee list.log | xargs sed -i 's/error/nothing/g'
    – janos
    Commented Apr 10, 2012 at 13:16
grep -l @error * | xargs sed -i s/error/test/g

will work.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .