diff --git a/usr.bin/join/join.1 b/usr.bin/join/join.1 index 8c71ec0cb203..10e00f0de40d 100644 --- a/usr.bin/join/join.1 +++ b/usr.bin/join/join.1 @@ -106,13 +106,16 @@ option specifies the fields that will be output from each file for each line with matching join fields. Each element of .Ar list -has the form +has the either the form .Ql file_number.field , where .Ar file_number is a file number and .Ar field -is a field number. +is a field number, or the form +.Ql 0 +.Pq zero , +representing the join field. The elements of list must be either comma .Pf ( Dq , Ns ) or whitespace separated. @@ -216,9 +219,11 @@ modification and should not be used. .Sh STANDARDS The .Nm -command is expected to be -.St -p1003.2 -compatible. +command conforms to +.St -p1003.1-2001 +except for the requirement that there be no space between the +.Fl a +option and its argument. .Sh SEE ALSO .Xr awk 1 , .Xr comm 1 , diff --git a/usr.bin/join/join.c b/usr.bin/join/join.c index 0731646c6522..84ea61b31e49 100644 --- a/usr.bin/join/join.c +++ b/usr.bin/join/join.c @@ -405,6 +405,8 @@ outoneline(F, lp) for (cnt = 0; cnt < olistcnt; ++cnt) { if (olist[cnt].filenum == F->number) outfield(lp, olist[cnt].fieldno, 0); + else if (olist[cnt].filenum == 0) + outfield(lp, F->joinf, 0); else outfield(lp, 0, 1); } @@ -427,7 +429,12 @@ outtwoline(F1, lp1, F2, lp2) /* Output a pair of lines according to the join list (if any). */ if (olist) for (cnt = 0; cnt < olistcnt; ++cnt) - if (olist[cnt].filenum == 1) + if (olist[cnt].filenum == 0) { + if (lp1->fieldcnt >= F1->joinf) + outfield(lp1, F1->joinf, 0); + else + outfield(lp2, F2->joinf, 0); + } else if (olist[cnt].filenum == 1) outfield(lp1, olist[cnt].fieldno, 0); else /* if (olist[cnt].filenum == 2) */ outfield(lp2, olist[cnt].fieldno, 0); @@ -480,27 +487,33 @@ void fieldarg(option) char *option; { - u_long fieldno; + u_long fieldno, filenum; char *end, *token; while ((token = strsep(&option, ", \t")) != NULL) { if (*token == '\0') continue; - if (token[0] != '1' && token[0] != '2' || token[1] != '.') + if (token[0] == '0') + filenum = fieldno = 0; + else if ((token[0] == '1' || token[0] == '2') && + token[1] == '.') { + filenum = token[0] - '0'; + fieldno = strtol(token + 2, &end, 10); + if (*end) + errx(1, "malformed -o option field"); + if (fieldno == 0) + errx(1, "field numbers are 1 based"); + --fieldno; + } else errx(1, "malformed -o option field"); - fieldno = strtol(token + 2, &end, 10); - if (*end) - errx(1, "malformed -o option field"); - if (fieldno == 0) - errx(1, "field numbers are 1 based"); if (olistcnt == olistalloc) { olistalloc += 50; if ((olist = realloc(olist, olistalloc * sizeof(OLIST))) == NULL) err(1, NULL); } - olist[olistcnt].filenum = token[0] - '0'; - olist[olistcnt].fieldno = fieldno - 1; + olist[olistcnt].filenum = filenum; + olist[olistcnt].fieldno = fieldno; ++olistcnt; } } @@ -567,8 +580,8 @@ jbad: errx(1, "illegal option -- %s", ap); if (ap[2] != '\0') break; for (p = argv + 2; *p; ++p) { - if (p[0][0] != '1' && - p[0][0] != '2' || p[0][1] != '.') + if (p[0][0] == '0' || (p[0][0] != '1' && + p[0][0] != '2' || p[0][1] != '.')) break; len = strlen(*p); if (len - 2 != strspn(*p + 2, "0123456789"))