logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git
commit: 47b057e876d1034b3dcd40626a3280e49a52ff92
parent c5e080d03c86c235483a97ae6509ebf84a55f552
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Wed, 25 Sep 2024 18:27:16 +0200

cmd/paste: add support for -z option

Diffstat:

Mcmd/paste.18+++++++-
Mcmd/paste.c18+++++++++++-------
Mtest-cmd/paste.sh7++++++-
3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/cmd/paste.1 b/cmd/paste.1 @@ -41,7 +41,7 @@ .Nd merge corresponding or subsequent lines of files .Sh SYNOPSIS .Nm -.Op Fl s +.Op Fl sz .Op Fl d Ar list .Ar .Sh DESCRIPTION @@ -99,6 +99,8 @@ file is replaced with the tab character, unless otherwise specified by the .Fl d option. +.It Fl z +Delimiter is NULL not newline. .El .Pp If @@ -138,6 +140,10 @@ environment variable: should be compliant with the IEEE Std 1003.1-2024 (“POSIX.1”) specification. +.Pp +The +.Fl z +option is an extension. .Sh HISTORY A .Nm diff --git a/cmd/paste.c b/cmd/paste.c @@ -46,6 +46,7 @@ static wchar_t *delim; static int delimcnt; +static wint_t linedelim = L'\n'; static int parallel(char **); static int sequential(char **); @@ -65,7 +66,7 @@ main(int argc, char *argv[]) setlocale(LC_CTYPE, ""); seq = 0; - while((ch = getopt(argc, argv, "d:s")) != -1) + while((ch = getopt(argc, argv, "d:sz")) != -1) switch(ch) { case 'd': @@ -83,6 +84,9 @@ main(int argc, char *argv[]) case 's': seq = 1; break; + case 'z': + linedelim = L'\0'; + break; case '?': default: usage(); @@ -170,13 +174,13 @@ parallel(char **argv) } else if((ch = delim[(lp->cnt - 1) % delimcnt])) putwchar(ch); - if(ich == '\n') continue; + if(ich == linedelim) continue; do { putwchar(ich); - } while((ich = getwc(lp->fp)) != WEOF && ich != '\n'); + } while((ich = getwc(lp->fp)) != WEOF && ich != linedelim); } - if(output) putwchar('\n'); + if(output) putwchar(linedelim); } return (0); @@ -210,12 +214,12 @@ sequential(char **argv) if(delim[cnt] != '\0') putwchar(delim[cnt]); if(++cnt == delimcnt) cnt = 0; } - if(ch != '\n') + if(ch != linedelim) putwchar(ch); else needdelim = 1; } - if(needdelim) putwchar('\n'); + if(needdelim) putwchar(linedelim); if(fp != stdin) (void)fclose(fp); } @@ -254,6 +258,6 @@ tr(wchar_t *arg) static void usage(void) { - (void)fprintf(stderr, "usage: paste [-s] [-d delimiters] file ...\n"); + (void)fprintf(stderr, "usage: paste [-sz] [-d delimiters] file ...\n"); exit(1); } diff --git a/test-cmd/paste.sh b/test-cmd/paste.sh @@ -4,7 +4,7 @@ WD="$(dirname "$0")/../" target="${WD}/cmd/paste" -plans=1 +plans=2 . "${WD}/test-cmd/tap.sh" banzai=$(mktemp) @@ -16,3 +16,8 @@ cut -b 501- -n "$banzai" > "${banzai}.2" t_file concat "$banzai" -d "\0" "${banzai}.1" "${banzai}.2" rm "$banzai" "${banzai}.1" "${banzai}.2" + +t_foobar_z() { + printf '%s\0' foo bar baz | "$target" -z - - +} +t_cmd foobar_z "$(printf 'foo\tbar\0baz\t\0')" t_foobar_z