From sjackman at gmail.com Fri Mar 14 01:53:02 2008 From: sjackman at gmail.com (Shaun Jackman) Date: Thu, 13 Mar 2008 16:53:02 -0700 Subject: [TRE-general] [PATCH] Implement grep -o and -b Message-ID: <7f45d9390803131653t66b126a9i2cb81d28ec114a90@mail.gmail.com> The following patch implements -o, --only-matching and -b, --byte-offset for compatibility with GNU grep. Comments are welcome. Cheers, Shaun 2008-03-13 Shaun Jackman * src/agrep.c: Add the options -o, --only-matching and -b, --byte-offset for compatibility with GNU grep. --- tre-0.7.5.orig/src/agrep.c 2006-12-09 12:31:13.000000000 -0800 +++ tre-0.7.5/src/agrep.c 2008-03-13 16:44:08.000000000 -0700 @@ -45,7 +45,7 @@ /* Short options. */ static char const short_options[] = -"cd:e:hiklnqsvwyBD:E:HI:MS:V0123456789"; +"bcd:e:hiklnoqsvwyBD:E:HI:MS:V0123456789"; static int show_help; char *program_name; @@ -60,6 +60,7 @@ static struct option const long_options[] = { {"best-match", no_argument, NULL, 'B'}, + {"byte-offset", no_argument, NULL, 'b'}, {"color", no_argument, NULL, COLOR_OPTION}, {"colour", no_argument, NULL, COLOR_OPTION}, {"count", no_argument, NULL, 'c'}, @@ -76,6 +77,7 @@ {"max-errors", required_argument, NULL, 'E'}, {"no-filename", no_argument, NULL, 'h'}, {"nothing", no_argument, NULL, 'y'}, + {"only-matching", no_argument, NULL, 'o'}, {"quiet", no_argument, NULL, 'q'}, {"record-number", no_argument, NULL, 'n'}, {"regexp", required_argument, NULL, 'e'}, @@ -140,10 +142,12 @@ -M, --delimiter-after print record delimiter after record if -d is used\n\ -n, --record-number print record number with output\n\ --line-number same as -n\n\ + -o, --only-matching show only the part of a record that matches\n\ -q, --quiet, --silent suppress all normal output\n\ -s, --show-cost print match cost with output\n\ --colour, --color use markers to distinguish the matching \ strings\n\ + -b, --byte-offset print the byte offset with output lines\n\ --show-position prefix each output record with start and end\n\ position of the first match within the record\n")); printf("\n"); @@ -187,6 +191,7 @@ static int list_files; /* List matching files. */ static int color_option; /* Highlight matches. */ static int print_position; /* Show start and end offsets for matches. */ +static int only_matching_option; /* Show only the part of a record that matches. */ static int best_match; /* Output only best matches. */ static int best_cost; /* Best match cost found so far. */ @@ -367,7 +372,7 @@ memset(&match, 0, sizeof(match)); if (best_match) match_params.max_cost = best_cost; - if (color_option || print_position) + if (color_option || print_position || only_matching_option) { match.pmatch = pmatch; match.nmatch = 1; @@ -414,10 +419,13 @@ printf("%d:", recnum); if (print_cost) printf("%d:", match.cost); - if (print_position) + if (print_position == 1) { printf("%d-%d:", invert_match ? 0 : (int)pmatch[0].rm_so, invert_match ? record_len : (int)pmatch[0].rm_eo); + } else if (print_position == 2) { + printf("%d:", (int)pmatch[0].rm_so); + } /* Adjust record boundaries so we print the delimiter before or after the record. */ @@ -433,7 +441,12 @@ pmatch[0].rm_eo += delim_len; } - if (color_option && !invert_match) + if (only_matching_option && !invert_match) + { + printf("%.*s\n", (int)(pmatch[0].rm_eo - pmatch[0].rm_so), + record + pmatch[0].rm_so); + } + else if (color_option && !invert_match) { printf("%.*s", (int)pmatch[0].rm_so, record); printf("\33[%sm", highlight); @@ -507,6 +520,10 @@ switch (c) { + case 'b': + /* Print the byte offset within the input file before each line of output. */ + print_position = 2; + break; case 'c': /* Count number of matching records. */ count_matches = 1; @@ -541,6 +558,10 @@ /* Print record number of matching record. */ print_recnum = 1; break; + case 'o': + /* Show only the part of a record that matches. */ + only_matching_option = 1; + break; case 'q': be_silent = 1; break;