|
|
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.