Javier Salas
Javier Salas

Reputation: 1188

grep in a directory and return just 1 result for each file in Unix Shell scripting

I'm trying to grep into a directory which has a couple of files, I'm trying to grep by IP address, my problem is, in a single file the ip address is repeated at least 3 or 4 times, and I just want to get 1 result and continue with the grep in the other file

This is what I'm trying to do and I don't have any luck with it.

grep 10.01.10.0 log/MY_DIRECTORY_FILES* | sort -t . -k 2 | head -1

This is just returning 1 result.

Upvotes: 2

Views: 348

Answers (2)

Javier Salas
Javier Salas

Reputation: 1188

Thanks to Etan Reisen This was his solution and it works for me!

grep -l 10.01.10.0 log/MY_DIRECTORY_FILES* | wc -l

I verified using grep -l 10.01.10.0 log/MY_DIRECTORY_FILES* and is only showing 1 result.

Thanks

Upvotes: 1

Etan Reisner
Etan Reisner

Reputation: 80931

head -1 returns the first line of the entire input it sees. You have it at the end of your sorted pipeline.

So grep spits out every matching line from every file. sort then sorts all the lines and outputs them. head then returns the very first line it sees.

That's not what you want. You want grep to stop after the first match in each file. Fortunately, that's what the -m option to grep does.

-m NUM, --max-count=NUM

Stop reading a file after NUM matching lines.  If the  input  is
standard  input  from a regular file, and NUM matching lines are
output, grep ensures that the standard input  is  positioned  to
just  after the last matching line before exiting, regardless of
the presence of trailing context lines.  This enables a  calling
process  to resume a search.  When grep stops after NUM matching
lines, it outputs any trailing context lines.  When  the  -c  or
--count  option  is  also  used,  grep  does  not output a count
greater than NUM.  When the -v or --invert-match option is  also
used, grep stops after outputting NUM non-matching lines.

So you want to use:

grep -m 1 10.01.10.0 log/MY_DIRECTORY_FILES* | sort -t . -k 2

If your version of grep (OpenBSD? Solaris?) doesn't have the -m option (and doesn't have any other equivalent option) then you have to run grep multiple times.

for file in log/MY_DIRECTORY_FILES*; do
    grep 10.01.10.0 "$file" | head -n 1
done | sort -t . -k 2

You could also, to avoid running grep N times, use something like this (with gawk):

awk '/10.01.10.0/ {print; nextfile}' log/MY_DIRECTORY_FILES*

For non-gawk you would need something more like this (untested):

awk '!f && /10.01.10.0/ {print; f=1; next} oARGIND != ARGIND {f=0; oARGIND=ARGIND}' log/MY_DIRECTORY_FILES*

Upvotes: 3

Related Questions