codeholic24
codeholic24

Reputation: 995

How to grep the exact match and print only that match

I have file's will lot's of data , need to print the exact keyword in following format : Filename : Keyword : line number

[Note : need to search recursively the entire directory for a keyword]

For example : I want to search keyword : abcxyz

Data in file is like below

abcxyz.fgh

gfhj.abcxyz

i have a book with name abcxyz.sh

where is my brother called : abcxyz.fsdghj raju how are you 

afsgdjj kllf

ghjakl  ra jksu ldlahlalfb  afhkflkaf dbllf jll  afl;bnhafl

When i am using this following command : grep "abcxyz" *.* it's printing entire line that i don't need

Expected Output :

Filename : abcxyz.fgh    : line number 
Filename : gfhj.abcxyz   : line number
Filename : abcxyz.sh     : line number
Filename : abcxyz.fsdghj : line number 

Upvotes: 2

Views: 3638

Answers (2)

Rishabh Kumar
Rishabh Kumar

Reputation: 2430

Here you go

grep -roHn "\S*Your_text_here\S*" *

tags

-r : recursively in the directory

-o : only the matched part

-H : with file name

-n : with line number

then tweaked the regex to include every characters except space, tabs and newline around your matched pattern using \S . Note : If you just want alphabets and numbers and no special symbols use \w instead.

and then the final '*' to indicate to search every file and folder in your current directory. So to use this command first cd to the required directory.

Upvotes: 6

RavinderSingh13
RavinderSingh13

Reputation: 133780

This should be a job for awk, could you please try following, written and tested with shown samples in GNU awk. Please mention absolute path in place of . to get run it for any directory in find command.

The output should be filename : matched string(s) : line number for all files.

You could run following find command:

find . -type f -exec awk -f script.awk {} +

Where script.awk is as follows:

cat script.awk
BEGIN{ OFS=" : " }
NF{
  val=""
  for(i=1;i<=NF;i++){
    if($i~/abcxyz/){
      val=(val?val OFS:"")$i
    }
  }
  if(val){
    print FILENAME,val,FNR
  }
}

For your shown samples(considering empty lines in it), sample output will be as follows.

Input_file  :  abcxyz.fgh     :  1
Input_file  :  gfhj.abcxyz    :  3
Input_file  :  abcxyz.sh      :  5
Input_file  :  abcxyz.fsdghj  :  7

Explanation: Adding detailed explanation for above.

BEGIN{ OFS=" : " }              ##Setting OFS to space colon space in BEGIN section of this program.
NF{                             ##Checking condition if line is NOT empty then do following.
  val=""
  for(i=1;i<=NF;i++){           ##Traversing through all field values here.
    if($i~/abcxyz/){            ##checking condition if field is matching abcxyz then do following.
      val=(val?val OFS:"")$i    ##Creating val which has value of current field and keep adding it.
    }
  }
  if(val){                      ##Checking condition if val is NOT NULL then do following.
    print FILENAME,val,FNR      ##Printing FILENAME val and FNR here.
  }
}
' 

Upvotes: 3

Related Questions