3

I am trying to use grep to find some tex files containing the pattern ->-:

grep -R -- "->-" *.tex

But this doesn't work. If I do:

grep -R -- "->-"

instead, it works, but is really slow and gives me clearly not only tex files but also matches lots of other file (for example binary files).

What would be the fastest way to do this search?

4 Answers 4

7

Try find and grep instead, with -exec:

find path_to_tex_files_directory -name "*.tex" -exec grep -- "->-" {} \;

or with xargs

find path_to_tex_files_directory -name "*.tex" | xargs grep -- "->-"
1
  • 1
    GNU find also let's you use -exec grep -- "->-" {} + in order to run grep on multiple files at a time. And when it's combined with GNU xargs, find ... -print0 | xargs -0 ... can be used, so that tricky filenames don't cause any issues. Commented Feb 25, 2015 at 15:54
6

The problem is that -R tells grep to recursively search through all files in the directory. So, you can't combine it with a specific group of files. Therefore, you can either use find as suggested by @KM., or shell globbing:

$ shopt -s globstar
$ grep -- "->-" **/*.tex

The shopt command activates bash's globstar feature:

globstar
                  If set, the pattern ** used in a pathname expansion con‐
                  text will match all files and zero or  more  directories
                  and  subdirectories.  If the pattern is followed by a /,
                  only directories and subdirectories match.

You then give **/*.tex as a pattern and that will match all .tex files in the current directory and any subdirectories.

If you're using zsh, there's no need for the shopt (which is a bash feature anyway) since zsh can do this by default.

1
  • Since I am using zsh this seems to be the easiest syntax and it also works fast enough for me.
    – student
    Commented Feb 20, 2015 at 16:03
3

If your grep supports it1, you could use the --include switch:

grep -R --include '*.tex' -- "->-"

or

grep -R --include='*.tex' -- "->-"

1:
Available at least in GNU grep:

--include=GLOB
        Search only files whose base name matches GLOB

and OSX grep:

--include
        If specified, only files matching the given filename pattern are searched.
2

-R option stand for recursive, I guess you have no dir in pattern *.tex.

maybe try something like:

find . -name \*.tex -exec grep -l -- "->-" {} \;
  • you can drop -l option, if you don't care about filename
  • if you want to see filename and pattern:

    find . -name \*.tex -exec grep -l -- "->-" {} \; | xargs grep -- "->-"
    

    but that's a double grep, @KM solution seems better..

You must log in to answer this question.

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