Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grep only the first match and stop

Tags:

grep

I'm searching a directory recursively using grep with the following arguments hoping to only return the first match. Unfortunately, it returns more than one -- in-fact two the last time I looked. It seems like I have too many arguments, especially without getting the desired outcome. :-/

# grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/directory 

returns:

Pulsanti Operietur Pulsanti Operietur 

Maybe grep isn't the best way to do this? You tell me, thanks very much.

like image 595
Tim Kamm Avatar asked Dec 30 '12 18:12

Tim Kamm


People also ask

How do I stop grep on first match?

The grep command has an -m or --max-count parameter, which can solve this problem, but it might not work like you'd expect. This parameter will make grep stop matching after finding N matching lines, which works great as it will limit the output to one line, always containing the first match.

How do I stop grep search?

While executing a bash script it stalls on a grep command. The Terminal just stops doing anything and you have press CTRL+Z to stop the script.

How do you grep a case insensitive?

Case Insensitive Search By default, grep is case sensitive. This means that the uppercase and lowercase characters are treated as distinct. To ignore case when searching, invoke grep with the -i option (or --ignore-case ).


2 Answers

-m 1 means return the first match in any given file. But it will still continue to search in other files. Also, if there are two or more matched in the same line, all of them will be displayed.

You can use head -1 to solve this problem:

grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -1 

explanation of each grep option:

-o, --only-matching, print only the matched part of the line (instead of the entire line) -a, --text, process a binary file as if it were text -m 1, --max-count, stop reading a file after 1 matching line -h, --no-filename, suppress the prefixing of file names on output -r, --recursive, read all files under a directory recursively 
like image 71
mvp Avatar answered Oct 14 '22 09:10

mvp


You can pipe grep result to head in conjunction with stdbuf.

Note, that in order to ensure stopping after Nth match, you need to using stdbuf to make sure grep don't buffer its output:

stdbuf -oL grep -rl 'pattern' * | head -n1 stdbuf -oL grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -n1 stdbuf -oL grep -nH -m 1 -R "django.conf.urls.defaults" * | head -n1 

As soon as head consumes 1 line, it terminated and grep will receive SIGPIPE because it still output something to pipe while head was gone.

This assumed that no file names contain newline.

like image 27
Venkat Kotra Avatar answered Oct 14 '22 10:10

Venkat Kotra