redis-cliでHashデータをcsv出力する


概要

RedisのHashを一覧表示したい。
何も考えないと、keysしてから一つずつhgetallとか、hmgetする必要がある。

出来上がったシェル

#!/bin/sh
export REDIS_CLI_PATH=src/redis-cli
export HASH_NAME=$1
export FIELD_NAMES=${@:2:($#-1)}

if [ -z "${HASH_NAME}" ]; then
  echo "Usage: redisHashToCsv.sh [HASH_NAME] ([FIELD_NAMES])"
  echo "ex1) redisHashToCsv.sh people"
  echo "ex2) redisHashToCsv.sh people name address"
  exit 1
fi

if [ -z "${FIELD_NAMES}" ]; then
  # Print all keys
  ${REDIS_CLI_PATH} keys "${HASH_NAME}:*" | cut -f 2 | head -1 | awk '{system("${REDIS_CLI_PATH} --csv hkeys " $0)}'
  ${REDIS_CLI_PATH} keys "${HASH_NAME}:*" | cut -f 2 | awk '{system("${REDIS_CLI_PATH} --csv hvals " $0)}'
else
  # Print keys specified by args
  echo ${FIELD_NAMES} | tr " " ","
  ${REDIS_CLI_PATH} keys "${HASH_NAME}:*" | cut -f 2 | awk '{system("${REDIS_CLI_PATH} --csv hmget " $0 " ${FIELD_NAMES}")}'
fi

xargsがうまく改行を処理できず、awkでゴリっとやりました。

実行例1 ハッシュキーのみ指定(非推奨)

[ec2-user@ip-172-30-2-184 redis-5.0.8]$ ./redisHashToCsv.sh people
"_class","name","age","address"
"redisreposample.Person","hoge","20",""
"redisreposample.Person","moge","35","2-2-2"
"redisreposample.Person","toge","3-3-3"
[ec2-user@ip-172-30-2-184 redis-5.0.8]$

3行目はageフィールドがnilなので、詰まって表示されてしまってます。
あと、hkeysとhvalsのキー順は常に同じであることを祈ります。

実行例2 ハッシュキー+フィールドリストを指定(推奨)

[ec2-user@ip-172-30-2-184 redis-5.0.8]$ ./redisHashToCsv.sh people name age address
name,age,address
"hoge","20",""
"moge","35","2-2-2"
"toge",NIL,"3-3-3"
[ec2-user@ip-172-30-2-184 redis-5.0.8]$

こっちのパターンだとnilが"NIL"と表示されてズレなくてよい感じです。

動作確認環境

[ec2-user@ip-172-30-2-184 redis-5.0.8]$ uname -a
Linux ip-172-30-2-184.ap-northeast-1.compute.internal 4.14.177-139.254.amzn2.x86_64 #1 SMP Thu May 7 18:48:23 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[ec2-user@ip-172-30-2-184 redis-5.0.8]$ src/redis-cli -v
redis-cli 5.0.8
[ec2-user@ip-172-30-2-184 redis-5.0.8]$

参考