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]);