132

I am using the following command on a Unix server:

find . -type f -name "*.txt" | xargs grep -li 'needle'

Since grep -R is not available, I have to use this find/xargs solution. Every time a file cannot be opened, grep tells me this:

grep: can't open "foo.txt"

I want to get rid of this message, so I tried to redirect stderr to /dev/null, but somehow this is not working.

find . -type f -name "*.txt" | xargs grep -li 'needle' 2>/dev/null

I want to preserve stdout (i.e. write the results to the console), and only hide these grep error messages. Instead of 2>, I also tried &>, but this also did not work. How can I fix this?

4

2 Answers 2

196

In order to redirect stderr to /dev/null use:

some_cmd 2>/dev/null

You don't need xargs here. (And you don't want it! since it performs word splitting)

Use find's exec option:

find . -type f -name "*.txt" -exec grep -li needle {} +

To suppress the error messages use the -s option of grep:

From man grep:

-s, --no-messages Suppress error messages about nonexistent or unreadable files.

which gives you:

find . -type f -name "*.txt" -exec grep -lis needle {} +
1
  • Thank you @hek2mgl that solution works perfectly :) All the grep warnings are gone (regardless whether or not I use the -s flag). Also didn't know about the -exec possiblity.
    – r0f1
    Commented Jun 26, 2017 at 11:49
24

Just move the redirection to the first command, i.e.

find ... 2>/dev/null | xargs ...

Or you can enclose everything in parenthesis:

(find ... | xargs ...) 2>/dev/null
1
  • Thank you, but this also does not work :S (find . -type f -name ".txt" | xargs grep -li 'needle') 2>/dev/null Badly placed ()'s. find . -type f -name ".txt" 2>/dev/null | xargs grep -li 'needle' Ambiguous output redirect.
    – r0f1
    Commented Jun 26, 2017 at 11:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.