add a -u option: flush output after printing each value (unbuffered) - json2tsv - JSON to TSV converter
(HTM) git clone git://git.codemadness.org/json2tsv
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 658cf342ce46348def6651d715b404a40baadb4f
(DIR) parent 994b5ebefdc81372822b42917e254ee1b0728db0
(HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun, 23 Apr 2023 12:39:38 +0200
add a -u option: flush output after printing each value (unbuffered)
This works similar to the sed -u option.
Sometimes it can be useful to force flushing the data directly. For example for
streaming JSON data.
Diffstat:
M jaq | 13 +++++++------
M jaq.1 | 5 ++++-
M json2tsv.1 | 5 ++++-
M json2tsv.c | 8 ++++++--
4 files changed, 21 insertions(+), 10 deletions(-)
---
(DIR) diff --git a/jaq b/jaq
@@ -1,12 +1,13 @@
#!/bin/sh
-nflag=""
-if [ "$1" = "-n" ]; then
- nflag="-n"
+flags=""
+while [ $# -gt 0 ]; do
+ [ "$1" = "-n" -o "$1" = "-u" ] || break
+ flags="${flags} $1"
shift
-fi
+done
if [ $# -le 0 ]; then
- echo "usage: jaq [-n] <awk expressions...>" >&2
+ echo "usage: jaq [-n] [-u] <awk expressions...>" >&2
exit 1
fi
expr="$*"
@@ -14,7 +15,7 @@ expr="$*"
# POSIX way to simulate -o pipefail if JSON data is invalid.
statusfile="$(mktemp)" || exit 1
trap -- "rm -f \"${statusfile}\"" "EXIT"
-{ json2tsv ${nflag} -r -F '\x1f' -R '\x1e'; echo $? >"${statusfile}"; } | \
+{ json2tsv ${flags} -r -F '\x1f' -R '\x1e'; echo $? >"${statusfile}"; } | \
LC_ALL=C awk "BEGIN { FS = \"\x1f\"; RS = \"\x1e\" }${expr}"
statuscode="$(cat "${statusfile}" 2>/dev/null)$?"
[ "${statuscode}" = "00" ]
(DIR) diff --git a/jaq.1 b/jaq.1
@@ -1,4 +1,4 @@
-.Dd September 1, 2022
+.Dd April 17, 2023
.Dt JAQ 1
.Os
.Sh NAME
@@ -7,6 +7,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl n
+.Op Fl u
.Ar awk expressions...
.Sh DESCRIPTION
.Nm
@@ -26,6 +27,8 @@ The options are as follows:
.Bl -tag -width Ds
.It Fl n
Show the indices for array types (by default off).
+.It Fl u
+Unbuffered: flush output after printing each value (by default off).
.El
.Pp
The options
(DIR) diff --git a/json2tsv.1 b/json2tsv.1
@@ -1,4 +1,4 @@
-.Dd September 1, 2022
+.Dd April 17, 2023
.Dt JSON2TSV 1
.Os
.Sh NAME
@@ -8,6 +8,7 @@
.Nm
.Op Fl n
.Op Fl r
+.Op Fl u
.Op Fl F Ar fs
.Op Fl R Ar rs
.Sh DESCRIPTION
@@ -21,6 +22,8 @@ The options are as follows:
Show the indices for array types (by default off).
.It Fl r
Show all control-characters (by default off).
+.It Fl u
+Unbuffered: flush output after printing each value (by default off).
.It Fl F Ar fs
Use
.Ar fs
(DIR) diff --git a/json2tsv.c b/json2tsv.c
@@ -19,6 +19,7 @@
static int nflag = 0; /* -n flag: show indices count for arrays */
static int rflag = 0; /* -r flag: show all control-characters */
+static int uflag = 0; /* -u flag: flush output after printing each value */
static int fs = '\t', rs = '\n';
static void (*printvalue)(const char *, size_t);
@@ -120,7 +121,7 @@ processnode(struct json_node *nodes, size_t depth, const char *value, size_t val
printvalue(value, valuelen);
putchar(rs);
- if (ferror(stdout)) {
+ if ((uflag && fflush(stdout)) || ferror(stdout)) {
fprintf(stderr, "write error: <stdout>\n");
exit(2);
}
@@ -178,7 +179,7 @@ readchar(const char *s)
void
usage(const char *argv0)
{
- fprintf(stderr, "usage: %s [-n] [-r] [-F fs] [-R rs]\n", argv0);
+ fprintf(stderr, "usage: %s [-n] [-r] [-u] [-F fs] [-R rs]\n", argv0);
exit(3);
}
@@ -202,6 +203,9 @@ main(int argc, char *argv[])
case 'r':
rflag = 1;
break;
+ case 'u':
+ uflag = 1;
+ break;
case 'F':
if (i + 1 >= argc)
usage(argv[0]);