|
|
1.1 ! root 1: /* ! 2: * split.c ! 3: * Usage: split [ -n ] [ infile [ outfile ]] ! 4: * ! 5: * split copies its input file into n-line pieces ! 6: * with output filenames ending in "aa", "ab", ... "zz". ! 7: * "n" (default 1000) is the number of lines per output file, ! 8: * "infile" (default or "-" is standard input) is the file to read, ! 9: * "outfile" (default "x") is the initial part of the output file name. ! 10: * A "-n" option beginning with 'c' (e.g. "-c100000") splits ! 11: * a binary file into characters instead of an ASCII file into lines. ! 12: */ ! 13: ! 14: #include <stdio.h> ! 15: ! 16: /* ! 17: * Globals. ! 18: */ ! 19: int binary = 0; /* 0 for ASCII lines, 1 for binary characters */ ! 20: long chunk = 1000L; /* number of lines or chars per output file */ ! 21: FILE *ifp = stdin; /* input file pointer */ ! 22: char *outname = "xaa"; /* first output filename */ ! 23: ! 24: /* ! 25: * Functions. ! 26: */ ! 27: long atol(); ! 28: void copy(); ! 29: void fatal(); ! 30: char *malloc(); ! 31: void nextname(); ! 32: void options(); ! 33: char *strcat(); ! 34: char *strcpy(); ! 35: ! 36: main(argc, argv) int argc; char *argv[]; ! 37: { ! 38: register int c; ! 39: register FILE *ofp; ! 40: register char *mode; ! 41: register char *tail; ! 42: ! 43: options(argc, argv); ! 44: tail = outname + strlen(outname) - 1; ! 45: mode = (binary) ? "wb" : "w"; ! 46: while (!feof(ifp) && (c = getc(ifp)) != EOF) { ! 47: ungetc(c, ifp); ! 48: if ((ofp = fopen(outname, mode)) == NULL) ! 49: fatal("split: cannot open output file \"%s\"\n", ! 50: outname); ! 51: copy(ofp); ! 52: if (fclose(ofp) == EOF) ! 53: fatal("split: cannot close output file \"%s\"\n", ! 54: outname); ! 55: nextname(tail); ! 56: } ! 57: exit(0); ! 58: } ! 59: ! 60: /* ! 61: * Copy "chunk" lines or characters from "ifp" to "ofp". ! 62: */ ! 63: void copy(ofp) register FILE *ofp; ! 64: { ! 65: register int c; ! 66: register long num; ! 67: ! 68: for (num = chunk; (c = getc(ifp)) != EOF; ) { ! 69: putc(c, ofp); ! 70: if ((binary || c == '\n') && --num <= 0) ! 71: return; ! 72: } ! 73: } ! 74: ! 75: /* ! 76: * Cry and die. ! 77: * Avoids the nonportable "%r" format by assuming char * "cp" follows "fmt". ! 78: * The second argument is omitted if the "fmt" does not require it. ! 79: */ ! 80: void fatal(fmt, cp) register char *fmt, *cp; ! 81: { ! 82: fprintf(stderr, fmt, cp); ! 83: exit(1); ! 84: } ! 85: ! 86: /* ! 87: * Set "outname" to the next output file name. ! 88: * If there are no more output files, issue an error message and exit. ! 89: */ ! 90: void nextname(cp) register char *cp; ! 91: { ! 92: if (++*cp <= 'z') ! 93: return; ! 94: *cp = 'a'; ! 95: if (++*--cp <= 'z') ! 96: return; ! 97: fatal("split: too many output files\n"); ! 98: } ! 99: ! 100: /* ! 101: * Process command line options and initialize globals. ! 102: */ ! 103: void options(argc, argv) register int argc; register char *argv[]; ! 104: { ! 105: register char *cp; ! 106: ! 107: if (--argc > 0 && **++argv == '-') { ! 108: cp = ++*argv; ! 109: if (*cp == 'c') { ! 110: binary = 1; ! 111: ++cp; ! 112: } ! 113: chunk = atol(cp); ! 114: ++argv; ! 115: --argc; ! 116: } ! 117: if (chunk <= 0L || argc > 2) ! 118: fatal("Usage: split [ -n ] [ infile [ outfile ]]\n"); ! 119: if (argc > 0) { ! 120: cp = *argv++; ! 121: if (strcmp(cp, "-") != 0 ! 122: && (ifp = fopen(cp, (binary) ? "rb" : "r")) == NULL) ! 123: fatal("split: cannot open input file \"%s\"\n", cp); ! 124: } ! 125: if (argc > 1) { ! 126: cp = *argv++; ! 127: if ((outname = malloc(strlen(cp) + 3)) == NULL) ! 128: fatal("split: \"%s\" too long\n", cp); ! 129: strcpy(outname, cp); ! 130: strcat(outname, "aa"); ! 131: } ! 132: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.