Patch from Matt Kraai to implement uniq -[cdu]
authorEric Andersen <andersen@codepoet.org>
Sat, 9 Dec 2000 16:37:53 +0000 (16:37 -0000)
committerEric Andersen <andersen@codepoet.org>
Sat, 9 Dec 2000 16:37:53 +0000 (16:37 -0000)
applets/usage.c
coreutils/uniq.c
docs/busybox.pod
docs/busybox.sgml
uniq.c
usage.c

index 75c421a09dc5e009394c9840d1e4ba68b5372681..ae6cec8dfd8914e57e9e68c4b51a24abb15ae35e 100644 (file)
@@ -1365,6 +1365,10 @@ const char uniq_usage[] =
 #ifndef BB_FEATURE_TRIVIAL_HELP
        "\nDiscard all but one of successive identical lines from INPUT\n"
        "(or standard input), writing to OUTPUT (or standard output).\n"
+       "Options:\n"
+       "\t-c\tprefix lines by the number of occurrences\n"
+       "\t-d\tonly print duplicate lines\n"
+       "\t-u\tonly print unique lines\n"
 #endif
        ;
 #endif
index cfe6cca5e2d23026b6766c824e8b24d37742cc70..c0229aecb492c8d5e0a8ff7024e7d538b6cb2f27 100644 (file)
 #include <string.h>
 #include <errno.h>
 
+static int print_count;
+static int print_uniq = 1;
+static int print_duplicates = 1;
+
+static void print_line(char *line, int count, FILE *fp)
+{
+       if ((print_duplicates && count > 1) || (print_uniq && count == 1)) {
+               if (print_count)
+                       fprintf(fp, "%7d\t%s", count, line);
+               else
+                       fputs(line, fp);
+       }
+}
+
 int uniq_main(int argc, char **argv)
 {
        FILE *in = stdin, *out = stdout;
        char *lastline = NULL, *input;
+       int opt, count = 0;
 
        /* parse argv[] */
-       if ((argc > 1 && **(argv + 1) == '-') || argc > 3)
-               usage(uniq_usage);
+       while ((opt = getopt(argc, argv, "cdu")) > 0) {
+               switch (opt) {
+                       case 'c':
+                               print_count = 1;
+                               break;
+                       case 'd':
+                               print_duplicates = 1;
+                               print_uniq = 0;
+                               break;
+                       case 'u':
+                               print_duplicates = 0;
+                               print_uniq = 1;
+                               break;
+               }
+       }
 
-       if (argv[1] != NULL) {
-               in = xfopen(argv[1], "r");
-               if (argv[2] != NULL)
-                       out = xfopen(argv[2], "w");
+       if (argv[optind] != NULL) {
+               in = xfopen(argv[optind], "r");
+               if (argv[optind+1] != NULL)
+                       out = xfopen(argv[optind+1], "w");
        }
 
        while ((input = get_line_from_file(in)) != NULL) {
                if (lastline == NULL || strcmp(input, lastline) != 0) {
-                       fputs(input, out);
+                       print_line(lastline, count, out);
                        free(lastline);
                        lastline = input;
+                       count = 0;
                }
+               count++;
        }
+       print_line(lastline, count, out);
        free(lastline);
 
        return EXIT_SUCCESS;
index 2ddacd152ef686ef7bd807c0fc0d23c9da45c8da..5e47984398c05df78ae48d9d3b7b80ac8cd841de 100644 (file)
@@ -1954,6 +1954,12 @@ Usage: uniq [OPTION]... [INPUT [OUTPUT]]
 
 Discard all but one of successive identical lines from INPUT
 (or standard input), writing to OUTPUT (or standard output).
+       
+Options:
+
+       -c              prefix lines by the number of occurrences
+       -d              only print duplicate lines
+       -u              only print unique lines
 
 Example:
 
@@ -2286,4 +2292,4 @@ Enrique Zanardi <ezanardi@ull.es>
 
 =cut
 
-# $Id: busybox.pod,v 1.79 2000/12/08 20:38:00 andersen Exp $
+# $Id: busybox.pod,v 1.80 2000/12/09 16:37:53 andersen Exp $
index 184814125184c2f35c94aa64d439d0a43207b36e..7d86e19e2a770e3d1b2208e0c742613cdae43fe0 100644 (file)
                INPUT (or stdin), writing to OUTPUT (or stdout).
                </para>
 
+               <para>
+               Options:
+               </para>
+
+               <para>
+               <screen>
+               -c              prefix lines by the number of occurrences
+               -d              only print duplicate lines
+               -u              only print unique lines
+               </screen>
+               </para>
+
                <para>
                Example:
                </para>
diff --git a/uniq.c b/uniq.c
index cfe6cca5e2d23026b6766c824e8b24d37742cc70..c0229aecb492c8d5e0a8ff7024e7d538b6cb2f27 100644 (file)
--- a/uniq.c
+++ b/uniq.c
 #include <string.h>
 #include <errno.h>
 
+static int print_count;
+static int print_uniq = 1;
+static int print_duplicates = 1;
+
+static void print_line(char *line, int count, FILE *fp)
+{
+       if ((print_duplicates && count > 1) || (print_uniq && count == 1)) {
+               if (print_count)
+                       fprintf(fp, "%7d\t%s", count, line);
+               else
+                       fputs(line, fp);
+       }
+}
+
 int uniq_main(int argc, char **argv)
 {
        FILE *in = stdin, *out = stdout;
        char *lastline = NULL, *input;
+       int opt, count = 0;
 
        /* parse argv[] */
-       if ((argc > 1 && **(argv + 1) == '-') || argc > 3)
-               usage(uniq_usage);
+       while ((opt = getopt(argc, argv, "cdu")) > 0) {
+               switch (opt) {
+                       case 'c':
+                               print_count = 1;
+                               break;
+                       case 'd':
+                               print_duplicates = 1;
+                               print_uniq = 0;
+                               break;
+                       case 'u':
+                               print_duplicates = 0;
+                               print_uniq = 1;
+                               break;
+               }
+       }
 
-       if (argv[1] != NULL) {
-               in = xfopen(argv[1], "r");
-               if (argv[2] != NULL)
-                       out = xfopen(argv[2], "w");
+       if (argv[optind] != NULL) {
+               in = xfopen(argv[optind], "r");
+               if (argv[optind+1] != NULL)
+                       out = xfopen(argv[optind+1], "w");
        }
 
        while ((input = get_line_from_file(in)) != NULL) {
                if (lastline == NULL || strcmp(input, lastline) != 0) {
-                       fputs(input, out);
+                       print_line(lastline, count, out);
                        free(lastline);
                        lastline = input;
+                       count = 0;
                }
+               count++;
        }
+       print_line(lastline, count, out);
        free(lastline);
 
        return EXIT_SUCCESS;
diff --git a/usage.c b/usage.c
index 75c421a09dc5e009394c9840d1e4ba68b5372681..ae6cec8dfd8914e57e9e68c4b51a24abb15ae35e 100644 (file)
--- a/usage.c
+++ b/usage.c
@@ -1365,6 +1365,10 @@ const char uniq_usage[] =
 #ifndef BB_FEATURE_TRIVIAL_HELP
        "\nDiscard all but one of successive identical lines from INPUT\n"
        "(or standard input), writing to OUTPUT (or standard output).\n"
+       "Options:\n"
+       "\t-c\tprefix lines by the number of occurrences\n"
+       "\t-d\tonly print duplicate lines\n"
+       "\t-u\tonly print unique lines\n"
 #endif
        ;
 #endif