silvert@dalcs.UUCP (Bill Silvert) (03/07/87)
Here is a simple-minded utility to delete specified characters from files or from stdin. I found it necessary for all kinds of reformatting, and tr -d doesn't always do the job -- for example, if you need to remove newlines from an Epson graphics file (which I had to do today), tr removes all the nulls as well, which trashes the file. catch offers several options for designating characters -- octal, hex, decimal, character, and several abbreviations. catch -h lists them all. To compile, you need getopt(3). I also use efopen and efclose -- if you don't have these, use fopen and fclose. The errors() call is often called error(), but you can always do your own. ------------------couper ici------------------- /* similar to tr -d, remove selected characters from input file(s) */ #include <stdio.h> static char SCCSID[] = "@(#)catch.c Ver. 1.2, 87/03/06 16:40:37"; char *progname, *filename; int delete[64]; /* characters to delete */ int iplace = 0; main(argc,argv) int argc; char *argv[]; { FILE *efopen(), *fp; int c, getopt(); extern int optind; extern char *optarg; int value; progname = *argv; delete[0] = EOF; /* flags end of deletion list */ while((c = getopt(argc, argv, "hbfnrc:o:x:d:")) != EOF) switch(c) { case 'b': /* delete backspaces */ delete[iplace++] = '\b'; delete[iplace] = EOF; break; case 'f': /* delete formfeeds */ delete[iplace++] = '\f'; delete[iplace] = EOF; break; case 'n': /* delete newlines */ delete[iplace++] = '\n'; delete[iplace] = EOF; break; case 'r': /* delete carriage returns */ delete[iplace++] = '\r'; delete[iplace] = EOF; break; case 'c': /* delete all characters in following string */ for(c=0; optarg[c]; c++) delete[iplace++] = optarg[c]; delete[iplace] = EOF; break; case 'o': /* delete by octal code */ if(sscanf(optarg, "%o", &value) != 1) errors("cannot find octal value in %s", optarg); delete[iplace++] = value; delete[iplace] = EOF; break; case 'x': /* delete by hex code */ if(sscanf(optarg, "%x", &value) != 1) errors("cannot find hex value in %s", optarg); delete[iplace++] = value; delete[iplace] = EOF; break; case 'd': /* delete by decimal code */ if(sscanf(optarg, "%u", &value) != 1) errors("cannot find decimal value in %s", optarg); delete[iplace++] = value; delete[iplace] = EOF; break; case 'h': default: help(c); exit(1); } switch(argc - optind) { case 0: filename = ""; copy(stdin); break; default: for(; optind<argc; optind++) { filename = argv[optind]; fp = efopen(filename, "r"); copy(fp); efclose(fp); } } exit(0); } help(c) char c; { fprintf(stderr, "%s: Options are:\n", progname); fprintf(stderr, "\t-b\tdelete backspaces\n"); fprintf(stderr, "\t-f\tdelete formfeeds\n"); fprintf(stderr, "\t-n\tdelete newlines\n"); fprintf(stderr, "\t-r\tdelete returns\n"); fprintf(stderr, "\t-cCCC\tdelete character[s] CCC\n"); fprintf(stderr, "\t-dNNN\tdelete decimal NNN\n"); fprintf(stderr, "\t-bNNN\tdelete octal NNN\n"); fprintf(stderr, "\t-oNNN\tdelete octal NNN\n"); fprintf(stderr, "\t-xNN\tdelete hex NN\n"); } copy(fp) FILE *fp; { int c; while ((c=getc(fp)) != EOF ) { for(iplace=0; delete[iplace] != EOF; iplace++) if(c == delete[iplace]) break; if(delete[iplace] == EOF) putchar(c); /* only if we reach the end */ } } -- Bill Silvert Marine Ecology Laboratory, Dartmouth, NS, Canada CDN or BITNET: silvert@cs.dal.cdn -- UUCP: ..!{seismo|utai}!dalcs!silvert ARPA: silvert%dalcs.uucp@seismo.CSS.GOV -- CSNET: silvert%cs.dal.cdn@ubc.csnet