(patch for Bash) Awk's NF for 'read'

(patch for Bash) Awk's NF for 'read'

Post by William Par » Wed, 05 Mar 2003 07:57:14



I got tired of doing something like
    ... | awk '{print NF, $0} | read a b c ...
or
    read -a var
    NF=${#var[*]}
    a=${var[0]}
    b=${var[1]}
    c=${var[2]}
    ...

Here is patch to get the number of fields that would have resulted,
given current IFS.  
    read -N
will create shell variable NF which is equivalent to Awk's NF.  Use at
your risk, and enjoy.

--

Linux solution for data management and processing.

--- ../bash-2.05b/builtins/read.def     Tue Mar 19 14:33:41 2002

   int rlind;
 #endif

+  int awk_NF = 0;                      /* Awk's NF (number of fields) */
+
   USE_VAR(size);
   USE_VAR(i);

   delim = '\n';                /* read until newline */

   reset_internal_getopt ();
-  while ((opt = internal_getopt (list, "ersa:d:n:p:t:u:")) != -1)
+  while ((opt = internal_getopt (list, "ersa:d:n:p:t:u:F:N")) != -1)
     {
       switch (opt)

        case 'd':
          delim = *list_optarg;
          break;
+       case 'N':
+           awk_NF = 1;
+           break;
        default:
          builtin_usage ();

   retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;

+  /* Shell variable NF will be assigned the number of fields (Awk's NF) that
+   * would have produced for the given IFS.  You can feed input through
+   *   awk '{print NF, $0}'
+   * or use array variable
+   *   read -a var ...
+   *   NF=${#var[*]}
+   * but
+   *   read -N
+   * is less typing.
+   *

+   */
+  if (awk_NF) {
+      WORD_LIST *alist;
+      int i;
+
+      alist = list_string (input_string, ifs_chars, 0);
+      i = list_length ((GENERIC_LIST *)alist);
+      bind_var_to_int ("NF", i);
+      dispose_words (alist);
+  }
+
 #if defined (ARRAY_VARS)
   /* If -a was given, take the string read, break it into a list of words,
      an assign them to `arrayname' in turn. */