[TRE-general] [PATCH] Implement grep -o and -b

Shaun Jackman sjackman at gmail.com
Fri Mar 14 01:53:02 EET 2008


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  <sjackman at gmail.com>

	* 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;



More information about the TRE-general mailing list