1

Various posts in other forums have suggested that the best way to use grep to return a single line per file is using -m 1, which is the --max-count option. However, when I write the following line, I get only one file, not one line per file:

grep -m 1 "library" ./ -R

Returns a single file on a single line:

.//results/fig/fig_functions.R:# library(plyr)

Whereas

grep "library" ./ -R

Returns many files, each with multiple lines:

.//results/fig/fig_functions.R:# library(plyr)
.//results/fig/fig_functions.R:# library(grid)
.//src/rmd/genevese_params.html:library(sf) 
.//src/rmd/genevese_params.html:library(raster)
[many more lines and files...]

I would like the command to return all files containing the text, but only return one line per file. Am I using grep incorrectly or is there another way to do this?

1
  • If you only want to see what files have a match, and you don't care what the match actually is, use the -l option: grep -lR "library" . – glenn jackman Jan 21 '20 at 17:54
2

It's not working as expected because Macs use a BSD version of grep while the answers you're seeing are for GNU grep as found on Linux. They're very similar but not identical, and they handle -m differently. BSD grep treats -m as covering the full output, while GNU's version is per-file.

One way to get the result you describe is like this:

find . -type f -exec grep -H -m1 library '{}' \;

This uses find to get the path to every file in . (recursively, so it gets all sub-directories) an then runs grep -m1 on each of them. The -type f tells find to only get regular files, not directories and other things. The -H tells grep to print the names of matching files, not just the matching text.

Another way would be to install GNU grep, using Homebrew.

You must log in to answer this question.

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