diff --git a/doc/agrep.1.in b/doc/agrep.1.in index 81d3beb..912cc37 100644 --- a/doc/agrep.1.in +++ b/doc/agrep.1.in @@ -128,6 +128,14 @@ Only print the name of each input file which contains at least one match, suppressing normal output. The scanning for each file will stop on the first match. .TP +.BI \-m " NUM" "\fR,\fP \-\^\-max\-count=" NUM +Stop processing each input file after +.I NUM +matching (or non-matching if +.B \-v +was specified) lines. +A negative value is interpreted as infinity, which is the default. +.TP .BR \-n ", " \-\^\-record\-number Prefix each output record with its sequence number in the input file. The number of the first record is 1. diff --git a/src/agrep.c b/src/agrep.c index 377dbd8..9d2d0c6 100644 --- a/src/agrep.c +++ b/src/agrep.c @@ -44,7 +44,7 @@ /* Short options. */ static char const short_options[] = -"cd:e:hiklnqsvwyBD:E:HI:MS:V0123456789-:"; +"cd:e:hiklm:nqsvwyBD:E:HI:MS:V0123456789-:"; static int show_help; char *program_name; @@ -72,6 +72,7 @@ static struct option const long_options[] = {"insert-cost", required_argument, NULL, 'I'}, {"invert-match", no_argument, NULL, 'v'}, {"line-number", no_argument, NULL, 'n'}, + {"max-count", required_argument, NULL, 'm'}, {"literal", no_argument, NULL, 'k'}, {"max-errors", required_argument, NULL, 'E'}, {"no-filename", no_argument, NULL, 'h'}, @@ -139,6 +140,7 @@ Output control:\n\ -H, --with-filename print the filename for each match\n\ -l, --files-with-matches only print FILE names containing matches\n\ -M, --delimiter-after print record delimiter after record if -d is used\n\ + -m, --max-count=NUM stop after NUM selected lines\n\ -n, --record-number print record number with output\n\ --line-number same as -n\n\ -q, --quiet, --silent suppress all normal output\n\ @@ -185,6 +187,7 @@ static int print_filename; /* Output filename. */ static int print_recnum; /* Output record number. */ static int print_cost; /* Output match cost. */ static int count_matches; /* Count matching records. */ +static int max_count; /* Max matching lines per input. */ static int list_files; /* List matching files. */ static int color_option; /* Highlight matches. */ static int print_position; /* Show start and end offsets for matches. */ @@ -449,6 +452,8 @@ tre_agrep_handle_file(const char *filename) printf("%.*s", record_len, record); } } + if (max_count > 0 && count >= max_count) + break; } } @@ -498,6 +503,7 @@ main(int argc, char **argv) be_silent = 0; tre_regaparams_default(&match_params); match_params.max_cost = 0; + max_count = -1; /* Parse command line options. */ while (1) @@ -542,6 +548,10 @@ main(int argc, char **argv) /* Only print files that contain matches. */ list_files = 1; break; + case 'm': + /* Stop after max_count matches. */ + max_count = atoi(optarg); + break; case 'n': /* Print record number of matching record. */ print_recnum = 1; @@ -652,6 +662,10 @@ Copyright (c) 2001-2009 Ville Laurikari .\n")); if (show_help) tre_agrep_usage(0); + /* Fail immediately if max_count is 0. */ + if (max_count == 0) + return EXIT_FAILURE; + if (color_option) { char *user_highlight = getenv("GREP_COLOR");