Hello! I sometimes use 'cat -E' as a quick check for lines with trailing white space. I understand that '$' was chosen as the end-of-line character due to its usage in regular expressions. However, I like to use a more conspicuous character, such as '@'. So, I thought, how about letting the user specify the end-of-line character? While doable with 'sed', it was quite easy to add an option to accomplish this. My proposed new syntax is:

cat -E -c @ ...

or

cat --show-ends --end-char=@ ...

It is minimally intrusive and does not affect backward compatibility: when one of the new options is not specified, the end-of-line character is still '$'. Alternatively, use of one of these options could automatically turn-on displaying an end-of-line character
(just add "show_ends = true;" within the new case).

Here's my patch submitted for your perusal. It is applied to coreutils-8.20, the current latest stable release. If you decide to include it, feel free to make any changes you see fit. Thanks!

-- Tom
diff -ru coreutils-8.20/doc/coreutils.texi coreutils-new/doc/coreutils.texi
--- coreutils-8.20/doc/coreutils.texi	2012-10-23 10:14:12.000000000 -0400
+++ coreutils-new/doc/coreutils.texi	2013-02-09 21:35:23.000000000 -0500
@@ -1509,6 +1509,12 @@
 @opindex --number-nonblank
 Number all nonempty output lines, starting with 1.
 
+@item -c
+@itemx --end-char=CHAR
+@opindex -c
+@opindex --end-char=CHAR
+With @option{-E}, use CHAR for the end of line character.
+
 @item -e
 @opindex -e
 Equivalent to @option{-vE}.
@@ -1517,7 +1523,7 @@
 @itemx --show-ends
 @opindex -E
 @opindex --show-ends
-Display a @samp{$} after the end of each line.
+Display a character (default @samp{$}) after the end of each line.
 
 @item -n
 @itemx --number
diff -ru coreutils-8.20/src/cat.c coreutils-new/src/cat.c
--- coreutils-8.20/src/cat.c	2012-10-23 10:14:12.000000000 -0400
+++ coreutils-new/src/cat.c	2013-02-09 21:48:13.000000000 -0500
@@ -94,8 +94,9 @@
 \n\
   -A, --show-all           equivalent to -vET\n\
   -b, --number-nonblank    number nonempty output lines, overrides -n\n\
+  -c, --end-char=CHAR      with -E, use CHAR for the end of line character\n\
   -e                       equivalent to -vE\n\
-  -E, --show-ends          display $ at end of each line\n\
+  -E, --show-ends          display a character (default $) at end of each line\n\
   -n, --number             number all output lines\n\
   -s, --squeeze-blank      suppress repeated empty output lines\n\
 "), stdout);
@@ -231,7 +232,8 @@
      bool number,
      bool number_nonblank,
      bool show_ends,
-     bool squeeze_blank)
+     bool squeeze_blank,
+     char end_char)
 {
   /* Last character read from the input buffer.  */
   unsigned char ch;
@@ -395,10 +397,11 @@
                     }
                 }
 
-              /* Output a currency symbol if requested (-e).  */
+              /* Output an end of line character (default currency symbol)
+		 if requested (-E).  */
 
               if (show_ends)
-                *bpout++ = '$';
+                *bpout++ = end_char;
 
               /* Output the newline.  */
 
@@ -543,10 +546,12 @@
   bool show_nonprinting = false;
   bool show_tabs = false;
   int file_open_mode = O_RDONLY;
+  char end_char = '$';
 
   static struct option const long_options[] =
   {
     {"number-nonblank", no_argument, NULL, 'b'},
+    {"end-char", required_argument, NULL, 'c'},
     {"number", no_argument, NULL, 'n'},
     {"squeeze-blank", no_argument, NULL, 's'},
     {"show-nonprinting", no_argument, NULL, 'v'},
@@ -572,7 +577,7 @@
 
   /* Parse command line options.  */
 
-  while ((c = getopt_long (argc, argv, "benstuvAET", long_options, NULL))
+  while ((c = getopt_long (argc, argv, "bc:enstuvAET", long_options, NULL))
          != -1)
     {
       switch (c)
@@ -582,6 +587,13 @@
           number_nonblank = true;
           break;
 
+        case 'c':
+          if (optarg[0] == '\0' || optarg[1] != '\0')
+	    error (EXIT_FAILURE, 0,
+		   "only one character is allowed at the end of each line");
+          end_char = optarg[0];
+          break;
+
         case 'e':
           show_ends = true;
           show_nonprinting = true;
@@ -761,7 +773,7 @@
           ok &= cat (ptr_align (inbuf, page_size), insize,
                      ptr_align (outbuf, page_size), outsize, show_nonprinting,
                      show_tabs, number, number_nonblank, show_ends,
-                     squeeze_blank);
+                     squeeze_blank, end_char);
 
           free (outbuf);
         }
diff -ru coreutils-8.20/tests/misc/cat-proc.sh coreutils-new/tests/misc/cat-proc.sh
--- coreutils-8.20/tests/misc/cat-proc.sh	2012-10-23 10:14:12.000000000 -0400
+++ coreutils-new/tests/misc/cat-proc.sh	2013-02-08 19:31:07.000000000 -0500
@@ -1,5 +1,6 @@
 #!/bin/sh
-# Ensure that cat -E produces same output as cat, module '$'s,
+# Ensure that cat -E and cat -E -c @ produce same output
+# as cat, module '$'s and '@'s, respectively,
 # even when applied to a file in /proc.
 
 # Copyright (C) 2006-2012 Free Software Foundation, Inc.
@@ -30,9 +31,11 @@
 # If that happens, consider choosing a file that's less likely to change,
 # or just filter out the changing lines.  The sed filter should help
 # to avoid any spurious numeric differences.
-cat -E $f | sed 's/[0-9][0-9]*/D/g' | tr -d '$' > out || fail=1
-cat    $f | sed 's/[0-9][0-9]*/D/g' | tr -d '$' > exp || fail=1
+cat -E      $f | sed 's/[0-9][0-9]*/D/g' | tr -d '$' > out1 || fail=1
+cat -E -c @ $f | sed 's/[0-9][0-9]*/D/g' | tr -d '@' > out2 || fail=1
+cat         $f | sed 's/[0-9][0-9]*/D/g' | tr -d '$' > exp  || fail=1
 
-compare exp out || fail=1
+compare exp out1 || fail=1
+compare exp out2 || fail=1
 
 Exit $fail

Reply via email to