commit 1807bcc4ce93dfe03368f5a02ac8aaa81869f1ec
parent 7c83e66679339067eb36124cd613203d5c0e11f2
Author: phoebos <ben@bvnf.space>
Date: Mon, 21 Mar 2022 19:58:43 +0000
allow other separator chars
Diffstat:
M | freq.1 | | | 14 | ++++++++++++-- |
M | freq.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';