Job Snijders([email protected]) on 2018.07.04 14:09:56 +0200: > Dear all, > > Following some back and forth on how disklabel output should be > formatted, I proposed to Kenneth to extend the column(1) utility. All that > was missing is the ability to right justify. I've longed for this > feature for a while: I often use 'column -t' to prettify data coming > from an awk pipeline.
funny, i use an awk script for that ;) code reads ok. as to -r: Linux: there is -R mentioned in http://man7.org/linux/man-pages/man1/column.1.html -R, --table-right columns Right align text in the specified columns. altough i dont know since when thats supported, because i could notfind that on any linux system i have access to and the util-linux change log does not mention it. They use -R because their -r is -r, --tree column Specify column to use tree-like output. Note that the circular dependencies and another anomalies in child and parent relation are silently ignored. FreeBSD doesn't have a right align in column. So i think, if a new feature and flag is acceptable, it should be -R /Benno > Example: > > job@vurt ~$ netstat -r | column -t -r | tail -5 > ff01::%iwm0/32 fe80::4708:d2be:9a Um 0 3 - 4 > iwm0 > ff01::%lo0/32 localhost Um 0 1 32768 4 > lo0 > ff02::/16 localhost UGRS 0 1 32768 8 > lo0 > ff02::%iwm0/32 fe80::4708:d2be:9a Um 0 3 - 4 > iwm0 > ff02::%lo0/32 localhost Um 0 1 32768 4 > lo0 > > > Patch courtesy of Kenneth R Westerback. OK? > > Index: column.1 > =================================================================== > RCS file: /cvs/src/usr.bin/column/column.1,v > retrieving revision 1.18 > diff -u -p -r1.18 column.1 > --- column.1 24 Oct 2016 13:53:05 -0000 1.18 > +++ column.1 4 Jul 2018 10:27:54 -0000 > @@ -40,6 +40,7 @@ > .Nm column > .Op Fl tx > .Op Fl c Ar columns > +.Op Fl r Op Ar list > .Op Fl s Ar sep > .Op Ar > .Sh DESCRIPTION > @@ -66,6 +67,16 @@ The options are as follows: > Output is formatted for a display > .Ar columns > wide. > +.It Fl r Op Ar list > +Table mode will right justify the column contents for the > +specified columns. > +.Ar list > +is a list of comma separated column numbers or column ranges. > +Column numbers start at 1. > +The list must not contain whitespace. > +If no > +.Ar list > +is provided then all columns will be right justified. > .It Fl s Ar sep > Specify a set of characters to delimit columns for the > .Fl t > Index: column.c > =================================================================== > RCS file: /cvs/src/usr.bin/column/column.c,v > retrieving revision 1.26 > diff -u -p -r1.26 column.c > --- column.c 22 Jun 2018 12:27:00 -0000 1.26 > +++ column.c 4 Jul 2018 10:28:00 -0000 > @@ -47,7 +47,8 @@ > void c_columnate(void); > void *ereallocarray(void *, size_t, size_t); > void input(FILE *); > -void maketbl(void); > +int rightjustify(const char *, const int); > +void maketbl(const int, const char *); > void print(void); > void r_columnate(void); > __dead void usage(void); > @@ -69,8 +70,8 @@ main(int argc, char *argv[]) > { > struct winsize win; > FILE *fp; > - int ch, tflag, xflag; > - char *p; > + int ch, rflag, tflag, xflag; > + char *p, *rcols; > const char *errstr; > > setlocale(LC_CTYPE, ""); > @@ -87,14 +88,19 @@ main(int argc, char *argv[]) > if (pledge("stdio rpath", NULL) == -1) > err(1, "pledge"); > > - tflag = xflag = 0; > - while ((ch = getopt(argc, argv, "c:s:tx")) != -1) { > + rcols = NULL; > + rflag = 0; tflag = xflag = 0; > + while ((ch = getopt(argc, argv, "c:r::s:tx")) != -1) { > switch(ch) { > case 'c': > termwidth = strtonum(optarg, 1, INT_MAX, &errstr); > if (errstr != NULL) > errx(1, "%s: %s", errstr, optarg); > break; > + case 'r': > + rflag = 1; > + rcols = optarg; > + break; > case 's': > if ((separator = reallocarray(NULL, strlen(optarg) + 1, > sizeof(*separator))) == NULL) > @@ -139,7 +145,7 @@ main(int argc, char *argv[]) > return eval; > > if (tflag) > - maketbl(); > + maketbl(rflag, rcols); > else if (*maxwidths >= termwidth) > print(); > else if (xflag) > @@ -207,18 +213,69 @@ print(void) > puts(table[row]->content); > } > > +int > +rightjustify(const char *rcols, const int col) > +{ > + const char *errstr; > + char c, *num, *temp; > + long long ch, rangestart; > + unsigned int i; > + > + if (rcols == NULL) > + return 1; > + > + temp = strdup(rcols); > + num = temp; > + rangestart = -1; > + > + c = 0; > + for (i = 0; i <= strlen(rcols); i++) { > + ch = temp[i]; > + if (ch == ',' || ch == '-') > + temp[i] = '\0'; > + if (temp[i] != '\0') > + continue; > + > + c = strtonum(num, 1, INT_MAX, &errstr); > + if (errstr != NULL) > + break; > + c--; /* Users are 1-based. Reality is 0-based. */ > + > + if (c == col) > + goto found; > + if (ch == '-') { > + rangestart = c; > + } else if ((ch == ',' || ch == '\0') && rangestart != -1) { > + if (rangestart <= col && c >= col) > + goto found; > + rangestart = -1; > + } > + num = temp + i + 1; > + } > + > + free(temp); > + return 0; > +found: > + free(temp); > + return 1; > +} > > void > -maketbl(void) > +maketbl(const int rflag, const char *rcols) > { > struct field **row; > int col; > > for (row = table; entries--; ++row) { > - for (col = 0; (*row)[col + 1].content != NULL; ++col) > - printf("%s%*s ", (*row)[col].content, > - maxwidths[col] - (*row)[col].width, ""); > - puts((*row)[col].content); > + for (col = 0; (*row)[col].content != NULL; ++col) { > + if (rflag && rightjustify(rcols, col)) > + printf("%*s ", maxwidths[col], > + (*row)[col].content); > + else > + printf("%-*s ", maxwidths[col], > + (*row)[col].content); > + } > + putchar('\n'); > } > } >
