133

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
  • 745
  • 6
  • 24
josh
  • 1,341
  • 2
  • 8
  • 4

7 Answers7

143

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

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

Elle H
  • 11,837
  • 7
  • 39
  • 42
98

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
  • 5,287
  • 1
  • 29
  • 28
33

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,429
  • 1
  • 23
  • 19
9

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
  • 5,239
  • 1
  • 43
  • 24
4

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

rg -w 's:text' . 

should do it

adiga
  • 34,372
  • 9
  • 61
  • 83
ms4720
  • 327
  • 1
  • 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
  • 2
    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

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
  • 117
  • 2
  • 13
  • 1
    the quotes are because of your shell. but yeah, use them it is easier. another example: `grep \\\` (i.e. escape the `\ ` and then the `<`) – gabriel Jun 15 '22 at 22:24
0

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
  • 66,414
  • 68
  • 253
  • 406