7

I am using Ubuntu machine and tried with below commands to search for a text:

This command to check if the word is present in a given directory recursively:

1) Here <hello> is the word which I am search for and it searches recursively in all files starting from current directory. It is working fine.

grep -r "<hello>" .

2) Now I want to restrict the search to only specific files, say to xml files only:

grep --include=\*.{java} -rnw '/home/myfolder/' -e "<hello>"

This time the command is taking more time and finally not giving any results. But my files has the content.

I have gone through this link - How do I find all files containing specific text on Linux? for writing my second command.

Is there any issue with my second command? Also is there an alternate command that performs fast?

Community
  • 1
  • 1
learner
  • 6,062
  • 14
  • 79
  • 139

3 Answers3

19

It might be better to use find, since grep's include/exclude can get a bit confusing:

find -type f -name "*.xml" -exec grep -l 'hello' {} +

This looks for files whose name finishes with .xml and performs a grep 'hello' on them. With -l (L) we make the file name to be printed, without the matched line.

Explanation

  • find -type f this finds files in the given directory structure.
  • -name "*.xml" selects those files whose name finishes with .xml.
  • -exec execute a command on every result of the find command.
  • -exec grep -l 'hello' {} + execute grep -l 'hello' on the given file. With {} + we are refering to the matched name (it is like doing grep 'hello' file but refering to the name of the file provided by the find command). Also, grep -l (L) returns the file name, not the match itself.
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • Thank you, How can I just see the file names instead the contents of the matching line also. – learner Jun 12 '15 at 10:45
  • 1
    Yes! For that, use `grep -l` (L) – fedorqui Jun 12 '15 at 10:46
  • also is it possible to include multiple files while searching, for example to search in both xml & java – learner Jun 12 '15 at 10:47
  • Also, I am just trying to understand the command. What is the meaning of `{} +` in your command. Can you please tell. – learner Jun 12 '15 at 10:50
  • Thank you, but can you please tell if I can include multiple files while searching, for example xml & java files? or I should run the command two times separately. – learner Jun 12 '15 at 10:55
  • 1
    @user3181365 sure, just add `-o -name "*.java"` as described in [find -name pattern that matches multiple patterns](http://stackoverflow.com/a/1133720/1983854) --> `find -type f -name "*.xml" -o -name "*.java"` – fedorqui Jun 12 '15 at 10:57
1

This is working for me, searching *.xml and *.java files, with GNU grep:

grep --include=\*.{xml,java} -rl '/path' -e 'hello'

In your question you had -w as flag, that means to match the whole word.

chaos
  • 8,162
  • 3
  • 33
  • 40
0

Ok, so the problem is - XML is not plain text, however similar it looks. It's therefore not really suitable for 'conventional' grepping.

Can I suggest having a look at [xml_grep][1] which is a utility that comes with the XML::Twig package for this purpose?

Or if you're able to give more specific examples of what your source content and desired outputs are, we can give more specific answers.

Anyway, other than that - I wouldn't do a recursive grep, but rather a find -exec. find lets you filter files first, and is quite efficient... but there really is no getting around the fact that you'll have to read every file that matches to check.

Sobrique
  • 52,974
  • 7
  • 60
  • 101