#include "gbos.h" /* cut -f N [-d C] [file]: print field N of each line. * * The delimiter defaults to TAB, like cut(1); -d takes the first character of * its argument, so `-d :` works - and since the shell has no quoting, `-d \\s` * is how you say space (\\t tab, \\n newline). A line with no delimiter is passed through * whole (what GNU cut does without -s), which is usually what you want when * filtering mixed output on a 40-column screen. */ #define MAXLINE 80 /* The shell has no quoting, so a space or a tab cannot be typed as an argument: "-d ' '" arrives as three tokens. Escapes are how you name them here - \s space, \t tab, \n newline, \\ backslash. */ static char unesc1(const char *s, unsigned char *used) { *used = 1; if (s[0] != '\\' || !s[1]) return s[0]; *used = 2; switch (s[1]) { case 's': return ' '; case 't': return '\t'; case 'n': return '\n'; case 'r': return '\r'; default: return s[1]; } } void main(void) { char *argv[8]; char line[MAXLINE]; unsigned char argc = argv_parse(argv, 8); char *fv = optval(argv, argc, 'f'); char *dv = optval(argv, argc, 'd'); unsigned char dused; char delim = dv ? unesc1(dv, &dused) : '\t'; unsigned char want = fv ? atou(fv) : 1; unsigned char len = 0, fd = NOFD, i, field, start, end; char *fname = 0; int ch; if (want == 0) want = 1; for (i = 0; i < argc; i++) { if (argv[i][0] == '-') continue; if (fv == argv[i] || dv == argv[i]) continue; fname = argv[i]; break; } if (fname) { fd = open(fname, O_READ); if (fd == EISDIR) { puts("cut: is a directory"); nl(); sexit(2); } if (fd == NOFD) { puts("cut: no such file"); nl(); sexit(2); } } for (;;) { if (fd == NOFD) { char c = readc(); ch = (c == EOF) ? -1 : c; } else ch = fgetc(fd); if (ch == '\r') continue; if (ch >= 0 && ch != '\n') { if (len < MAXLINE) line[len++] = (char)ch; continue; } if (ch < 0 && len == 0) break; /* walk to the wanted field */ field = 1; start = 0; for (i = 0; i <= len; i++) { if (i == len || line[i] == delim) { if (field == want) break; field++; start = (unsigned char)(i + 1); } } end = i; if (field == want && start <= len) writes(line + start, (unsigned char)(end - start)); nl(); len = 0; if (ch < 0) break; } if (fd != NOFD) close(fd); }