freq

count frequencies of keys in text
git clone git://bvnf.space/freq.git
Log | Files | Refs

commit 1807bcc4ce93dfe03368f5a02ac8aaa81869f1ec
parent 7c83e66679339067eb36124cd613203d5c0e11f2
Author: phoebos <ben@bvnf.space>
Date:   Mon, 21 Mar 2022 19:58:43 +0000

allow other separator chars

Diffstat:
Mfreq.1 | 14++++++++++++--
Mfreq.c | 27+++++++++++++++++++++++----
2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/freq.1 b/freq.1 @@ -6,6 +6,7 @@ .Nd count frequencies of keys in text .Sh SYNOPSIS .Nm +.Op Fl d Ar delim .Op Fl k Ar key .Op Ar file .Sh DESCRIPTION @@ -26,14 +27,23 @@ character, then the value of the field. .Pp The following options are supported: .Bl -tag -width Ds +.It Fl d Ar delim +Set the field delimiter to the character +.Ar delim . +The default is any character of class +.Vt space +in the current locale (see +.Xr isspace 3 ) . .It Fl k Ar key Count the frequencies of the field found at position .Ar key , -where fields are separated by any number of space characters in the current locale (see -.Xr isspace 3 ) . +where fields are separated by any number of +.Ar delim +characters. The default value of .Ar key is 1, meaning that the first fields on each line are counted. +To use the whole line as a key, use the special value of 0. If .Ar key fields are not found on a line, a warning is printed and the whole line is ignored. diff --git a/freq.c b/freq.c @@ -4,6 +4,10 @@ #include <string.h> #include <unistd.h> +enum { + SEP_DEFAULT = -1, +}; + void freq(FILE *f, int field); struct count { @@ -13,6 +17,7 @@ struct count { struct count *cs; size_t cs_len = 0; +char sep; size_t get_index(char *name) { @@ -57,15 +62,27 @@ print_freqs(void) { } int +is_sep(int c) { + if (sep == SEP_DEFAULT) + return isspace(c); + else + return (c == sep); +} + +int main (int argc, char **argv) { int c, field = 1; - while ((c = getopt(argc, argv, ":k:")) != -1) { + sep = SEP_DEFAULT; + while ((c = getopt(argc, argv, ":d:k:")) != -1) { switch (c) { + case 'd': + sep = optarg[0]; + break; case 'k': field = atoi(optarg); break; case '?': - fprintf(stderr, "usage: %s [-k fieldnum] [file]\n", argv[0]); + fprintf(stderr, "usage: %s [-d delim] [-k fieldnum] [file]\n", argv[0]); return 1; } } @@ -107,13 +124,15 @@ freq(FILE *f, int field) { linenum++; i = 0; field_start = line; + if (field == 0) + goto field_found; in_word = 0; cur_field = 1; /* eat up whitespace at front */ - while (isspace(line[i])) + while (is_sep(line[i])) i++; for (; i < n; i++) { - if (isspace(line[i])) { + if (is_sep(line[i])) { if (in_word) { if (cur_field == field) { line[i] = '\0';