grep-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

DRAFT: PROPOSAL: Add option 'piped-list' to read file list from stdin


From: José Bollo
Subject: DRAFT: PROPOSAL: Add option 'piped-list' to read file list from stdin
Date: Tue, 26 Apr 2022 08:03:13 +0200

This is just an idea. Why is it not possible to get the list of file 
from stdin? Why is it not already in grep? It seems so obvious and 
useful that is was maybe withdrawn before (for some good reason).

I was doing a script with

   file . [condition] -exec grep -q EXPR {} ; -print

but it could also be written

   file . [condition] | grep -pl EXPR

if the proposal is accepted.

With the two BIG advantages are:
  - there is only 2 processes, not 1 + the count of files
  - there is no need to check limit on size of arguments of a command

Here below the patch (not tested, just an idea here). More advanced 
usage could read from a file instead of stdin but it is of less 
importance IMHO.

Best regards
José Bollo

diff --git a/src/grep.c b/src/grep.c
index 4109ae4..98ffd84 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -555,6 +555,7 @@ static struct option const long_options[] =
    {"version", no_argument, NULL, 'V'},
    {"with-filename", no_argument, NULL, 'H'},
    {"word-regexp", no_argument, NULL, 'w'},
+  {"piped-list", no_argument, NULL, 'p'},
    {0, 0, 0, 0}
  };

@@ -1089,6 +1090,7 @@ static intmax_t max_count;        /* Max number
of selected lines from an input file.  */
  static bool line_buffered;    /* Use line buffering.  */
  static char *label = NULL;      /* Fake filename for stdin */
+static bool piped_list;         /* Read file list from stdin */


  /* Internal variables to keep track of byte count, context, etc. */
@@ -2000,6 +2002,7 @@ Pattern selection and interpretation:\n"), 
getprogname ());
        printf (_("\
  \n\
  Miscellaneous:\n\
+  -p, --piped-list          get file list from stdin\n\
    -s, --no-messages         suppress error messages\n\
    -v, --invert-match        select non-matching lines\n\
    -V, --version             display version information and exit\n\
@@ -2698,6 +2701,10 @@ main (int argc, char **argv)
          only_matching = true;
          break;

+      case 'p':
+       piped_list = true;
+        break;
+
        case 'q':
          exit_on_match = true;
          exit_failure = 0;
@@ -2986,27 +2993,49 @@ main (int argc, char **argv)
    if (fts_options & FTS_LOGICAL && devices ==
  READ_COMMAND_LINE_DEVICES) devices = READ_DEVICES;

-  char *const *files;
-  if (0 < num_operands)
-    {
-      files = argv + optind;
-    }
-  else if (directories == RECURSE_DIRECTORIES && 0 < last_recursive)
+  bool status = true;
+  if (piped_list)
      {
-      static char *const cwd_only[] = { (char *) ".", NULL };
-      files = cwd_only;
-      omit_dot_slash = true;
+      size_t size = 0;
+      char *file = NULL;
+      ssize_t rsize;
+      out_file = true;
+      while ((rsize = readline(&file, &size, stdin)) > 0)
+        {
+         if(file[rsize - 1] == '\n')
+           {
+             file[--rsize] = 0;
+           }
+          if (rsize > 0)
+           {
+             status &= grep_command_line_arg (file);
+           }
+       }
+      free(file);
      }
    else
      {
-      static char *const stdin_only[] = { (char *) "-", NULL };
-      files = stdin_only;
-    }
+      char *const *files;
+      if (0 < num_operands)
+        {
+          files = argv + optind;
+        }
+      else if (directories == RECURSE_DIRECTORIES && 0 <
  last_recursive)
+        {
+          static char *const cwd_only[] = { (char *) ".", NULL };
+          files = cwd_only;
+          omit_dot_slash = true;
+        }
+      else
+        {
+          static char *const stdin_only[] = { (char *) "-", NULL };
+          files = stdin_only;
+        }

-  bool status = true;
-  do
-    status &= grep_command_line_arg (*files++);
-  while (*files != NULL);
+      do
+        status &= grep_command_line_arg (*files++);
+      while (*files != NULL);
+    }

    return errseen ? EXIT_TROUBLE : status;
  }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]