I'm looking for a CLI tool that takes an arbitrary number of arguments $a, $b, $c, $d, etc., and writes $a"\0"$b"\0"$c"\0"$d
to stdout. Is there a standard tool that can do this that I can just use in the beginning of a pipe on the CLI? My implementation of echo
doesn't seem to allow for custom delimiters.
Asked
Active
Viewed 594 times
0

UTF-8
- 3,237
2 Answers
4
printf
can take care of this, nearly:
printf "%s\0" "$a" "$b" "$c" ...
printf
repeats its format string as much as necessary, in this case once per argument, so you end up with each argument followed by a null byte.
To get rid of the last null byte, use GNU head
:
printf "%s\0" "$a" "$b" "$c" ... | head -c-1
Zsh’s builtin print
can also do this, with no post-processing:
print -rNn "$a" "$b" "$c" ...
(-r
disables escape processing, -N
prints the arguments separated and terminated by null bytes, -n
disables the terminal newline. Thanks steeldriver for the tip!)

Stephen Kitt
- 434,908
-
Thanks! SE doesn't allow me to accept until 10 minutes have passed. Will accept shortly. – UTF-8 Jul 05 '19 at 13:25
3
The printf
command will repeat the format as often as necessary, so we can just do
print "%s\0"
We can see this in action:
$ printf "%s\0" hello there | hdump -8
00000000 68 65 6C 6C 6F 00 74 68 hello.th
00000008 65 72 65 00 ere.
$ printf "%s\0" hello there everyone out there | hdump -8
00000000 68 65 6C 6C 6F 00 74 68 hello.th
00000008 65 72 65 00 65 76 65 72 ere.ever
00000010 79 6F 6E 65 00 6F 75 74 yone.out
00000018 00 74 68 65 72 65 00 .there.
Note that is also puts a terminal NUL at the end of the string. If you don't want that, we can remove it, eg with sed 's/.$//'
$ printf "%s\0" hello there everyone out there | sed 's/.$//' | hdump -8
00000000 68 65 6C 6C 6F 00 74 68 hello.th
00000008 65 72 65 00 65 76 65 72 ere.ever
00000010 79 6F 6E 65 00 6F 75 74 yone.out
00000018 00 74 68 65 72 65 .there

Stephen Harris
- 44,540