awk '{ print "*" NF "\r"; for(i = 1; i <= NF; i++) { print "$" length($i) "\r\n" $i "\r" } }' sample | redis-cli --pipe
If redis is running on docker use:
awk '{ print "*" NF "\r"; for(i = 1; i <= NF; i++) { print "$" length($i) "\r\n" $i "\r" } }' sample | docker exec -i redis redis-cli --pipe
This is based on the ruby snippet described here that uses ruby String.bytesize
which is not exactly the same of awk's string length, so use this at your own risk.
For my usage this worked like a charm.
The version below supports bytesize using wc -c
, but it feels bad to perform a system call for every argument and it's also very slow.
awk '{ print "*" NF "\r"; for(i = 1; i <= NF; i++) { system("printf " $i "| wc -c | sed -e \"s/ *//\" -e \"s/^/$/\" -e \"s/$/\r/\""); print $i "\r" } }'
On Mac OS this awk's length()
seems to count the actual bytesize of a string.
$ echo -n 'Jose' | awk '{ print length($1) }'
4
$ echo -n 'José' | awk '{ print length($1) }'
5
If you have spaces on the last argument you can use something like this:
awk '{ argsize = 4; pos = 0; print "*" argsize "\r"; for(i = 1; i <= argsize; i++) { arg = (i == argsize) ? substr($0, pos + 1) : $i; print "$" length(arg) "\r\n" arg "\r"; pos += length(arg) + 1 } }'
where 4 is the number of arguments.This is the case for a command such as:
HSET my_set key {"key":"string with spaces"}
Unfortunately this only works for files where all the commands have the same number of arguments.