#define VERSION "uniq.c -- BDS Version 1.0 -- 6/20/82" /* * uniq - report repeated lines in a file * * Adapted for BDS C by Jeff Martin, from a program by the same * name written to run under the Unix (tm) operating system. * * From the manual page for the Unix command: * * "Uniq reads the input file comparing adjacent lines. In the * normal case, the second and succeeding copies of repeated * lines are removed; the remainder is written on the output * file. Input and output should always be different. Note * that repeated lines must be adjacent in order to be found. * If the -u flag is used, just the lines that * are not repeated in the original file are output. The -d * option specifies that one copy of just the repeated lines is * to be written. The normal mode output is the union of the * -u and -d mode outputs. * * "The -c option supersedes -u and -d and generates an output * report in default style but with each line preceded by a * count of the number of times it occurred. * * "The n arguments specify skipping an initial portion of each * line in the comparison: * * -n The first n fields together with any blanks before * each are ignored. A field is defined as a string of * non-space, non-tab characters separated by tabs and * spaces from its neighbors. * * ^n The first n characters are ignored. Fields are * skipped before characters." * * To compile: CC1 uniq.c * * To link: L2 uniq dio * or -- CLINK uniq -f dio */ #define STDERR 4 #include #include int fields; int letters; int linec; char mode; int uniq; char *skip(); char b1[1000], b2[1000]; struct _buf infile; main(argc, argv) int argc; char *argv[]; { dioinit(&argc, argv); fields = letters = linec = uniq = 0; mode = '\0'; while(argc > 1) { if(*argv[1] == '-') { if (isdigit(argv[1][1])) fields = atoi(&argv[1][1]); else mode = tolower(argv[1][1]); argc--; argv++; continue; } if(*argv[1] == '^') { letters = atoi(&argv[1][1]); argc--; argv++; continue; } if ((argc == 2) && (fopen(argv[1], infile) == ERROR)) { fprintf(STDERR,"Cannot open %s\n", argv[1]); exit(1); } break; } if (argc != 2) { usage(); exit(1); } if(gline(b1)) { dioflush(); exit(0); } for(;;) { linec++; if(gline(b2)) { pline(b1); dioflush(); exit(0); } if(!equal(b1, b2)) { pline(b1); linec = 0; do { linec++; if(gline(b1)) { pline(b2); dioflush(); exit(0); } } while(equal(b1, b2)); pline(b2); linec = 0; } } } usage() { fprintf(STDERR,"\n%s\n",VERSION); fputs("\nUsage: UNIQ [-u][-d][-c] [-n] [^n] input [>output]\n",STDERR); fputs("\t-u ==> just output unrepeated lines\n",STDERR); fputs("\t-d ==> output one copy of just repeated lines\n",STDERR); fputs("\t(default) ==> union of -u and -d options\n\n",STDERR); fputs("\t-c ==> prefix each output line with count of occurrences\n\n",STDERR); fputs("\t-n ==> skip first n fields in comparison\n",STDERR); fputs("\t^n ==> ignore first n characters (fields are skipped first)\n",STDERR); exit(1); } gline(buf) char buf[]; { if (fgets(buf,infile) == NULL) { *buf = 0; return(1); } buf[strlen(buf)-1] = '\0'; return(0); } pline(buf) char buf[]; { switch(mode) { case 'u': if(uniq) { uniq = 0; return; } break; case 'd': if(uniq) break; return; case 'c': printf("%4d ", linec); } uniq = 0; puts(buf); putchar('\n'); } equal(s1, s2) char s1[], s2[]; { char c; s1 = skip(s1); s2 = skip(s2); while((c = *s1++) != 0) if(c != *s2++) return(0); if(*s2 != 0) return(0); uniq++; return(1); } char * skip(s) char *s; { int nf, nl; nf = nl = 0; while(nf++ < fields) { while(*s == ' ' || *s == '\t') s++; while( !(*s == ' ' || *s == '\t' || *s == 0) ) s++; } while(nl++ < letters && *s != 0) s++; return(s); }  .