8

I'm using Mac 10.7.5 and on a bash shell. I'm trying to find instances of a string in a group of files but keep getting this error

Daves-MacBook-Pro:folder davea$ find . -name "*" | xargs grep 'state-icons'
xargs: grep: Argument list too long

How can I run the command (or a similar one) to avoid this error?

1
  • grep '...' <( find … ) maybe?
    – slhck
    Aug 6, 2013 at 16:58

2 Answers 2

9

You can use the -n option of xargs to limit the number of arguments.

find . -name "*" | xargs -n 20 grep 'state-icons'

But a better solution is to use -type f instead of -name "*" in order to limit the list to ordinary files, avoiding the error message for each folder.

Note that it does not work for files with whitespace in their names.

7
  • Would limiting the number of arguments potentially prevent the correct results from being displayed? Ultimately my goal is to find files with an instance of the desired string, as opposed to simply eliminating the error message.
    – Dave
    Aug 6, 2013 at 15:24
  • @Dave: No, grep will be run several times, with 20 file arguments each. You might add -type f to find to avoid errors when grep tries to open directories.
    – choroba
    Aug 6, 2013 at 15:27
  • 3
    There’s a risk that if the find reports, say, 61 files, then xargs will run grep four times –– three times with 20 files and once with 1 file. When grep is run with multiple files, it reports the name(s) of the file(s) where it finds matches; not so with only one filename argument. A trick that is commonly used to fix this is to say xargs -n 20 grep 'state-icons' /dev/null, so xargs will run grep three times with 21 files and once with 2 files –– the additional file, of course, being /dev/null, which will otherwise have no effect on the run. Aug 6, 2013 at 15:49
  • 2
    @Scott: You can also use the -H option of grep (if supported).
    – choroba
    Aug 6, 2013 at 16:11
  • @choroba: I don't have a Mac and I didn't have one seven years ago either. But on my machine it prints an error to stderr for each directory but it does print the filenames on stdout. What failure did you experience?
    – rici
    Jun 10, 2020 at 23:00
-2

What about this if you want to seach through the filename:

for x in ./**/*.*; do echo "$x" | grep 'state-icons' ; done

and this if you want to seach through the file content:

for x in ./**/*.*; do grep 'state-icons' "$x" ; done
3
  • 1
    That would run grep only on the file names, not on their contents.  Also, *.* does not mean “all files” (as it does in Windows); it restricts the search to files that have a . in their name. Feb 11, 2019 at 3:51
  • @Scott but the -name argument indicates that they want to search about the filename. If they want to search about the file content, just omit the echo and use grep 'state-icons' $x
    – youkaichao
    Feb 11, 2019 at 4:09
  • Please edit your answer to include that variation.   Oh, and I almost forgot: please quote your variables. Feb 11, 2019 at 4:15

You must log in to answer this question.

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