113

I am using the following command to grep stuff in subdirs

find . | xargs grep -s 's:text'

However, this also finds stuff like <s:textfield name="sdfsf"...../>

What can I do to avoid that so it just finds stuff like <s:text name="sdfsdf"/>

OR for that matter....also finds <s:text somethingElse="lkjkj" name="lkkj"

basically s:text and name should be on same line....

shiri
  • 735
  • 6
  • 23
josh
  • 1,141
  • 2
  • 7
  • 4

7 Answers7

130

You want the -w option to specify that it's the end of a word.

find . | xargs grep -sw 's:text'

Elle H
  • 11,328
  • 7
  • 36
  • 42
88

Use \b to match on "word boundaries", which will make your search match on whole words only.

So your grep would look something like

grep -r "\bSTRING\b"

adding color and line numbers might help too

grep --color -rn "\bSTRING\b"

From http://www.regular-expressions.info/wordboundaries.html:

There are three different positions that qualify as word boundaries:

  • Before the first character in the string, if the first character is a word character.
  • After the last character in the string, if the last character is a word character.
  • Between two characters in the string, where one is a word character and the other is not a word character.
cs01
  • 4,749
  • 1
  • 26
  • 27
31

You can drop the xargs command by making grep search recursively. And you normally don't need the 's' flag. Hence:

grep -wr 's:text' 
joctee
  • 2,275
  • 1
  • 21
  • 19
4

you could try rg, https://github.com/BurntSushi/ripgrep :

rg -w 's:text' . 

should do it

adiga
  • 31,610
  • 8
  • 53
  • 74
ms4720
  • 171
  • 11
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/17780631) – Jibin Balachandran Oct 30 '17 at 11:55
  • 4
    I did provide the answer: rg -w 's:text' . – ms4720 Nov 01 '17 at 08:13
  • 1
    There may be other reasons to suggest a nonstandard tool, but as a solution to a question about how to solve this with standard `grep` this is not particularly compelling or satisfying, especially given that `grep` has the same option. – tripleee Oct 18 '19 at 19:04
  • It depends on how deep and fat the directi – ms4720 Oct 24 '19 at 09:38
  • It depends on the number of files, ripgrep can be much faster and the find->xargs creates a new process for each file. – ms4720 Oct 24 '19 at 09:40
1

If you just want to filter out the remainder text part, you can do this.

xargs grep -s 's:text '

This should find only s:text instances with a space after the last t. If you need to find s:text instances that only have a name element, either pipe your results to another grep expression, or use regex to filter only the elements you need.

Stefan Kendall
  • 64,006
  • 65
  • 247
  • 399
1

Use -w option for whole word match. Sample given below:

[binita@ubuntu ~]# a="abcd efg"
[binita@ubuntu ~]# echo $a
abcd efg
[binita@ubuntu ~]# echo $a | grep ab
abcd efg
[binita@ubuntu ~]# echo $a | grep -w  ab
[binita@ubuntu ~]# echo $a | grep -w  abcd
abcd efg
Binita Bharati
  • 4,026
  • 1
  • 34
  • 22
0

This is another way of setting the boundaries of the word, note that it doesn't work without the quotes around it:

grep -r '\<s:text\>' .

MyNameIsTrez
  • 61
  • 1
  • 9