I have a Redis multicluster with 2 types of records:
4_123: 123
// and
123: 4_123
I'm removed records matching 4_* by KEY using:
redis-cli --scan --pattern 4_* | xargs -n 1 redis-cli DEL
there also address params for an exact cluster, that is why I used xargs -n 1 ... to avoid wrong cluster error.
Now my question is how can I delete records with VALUE matching this same pattern: '4_*'?
The only solution I've come up with so far is:
for i in $(redis-cli KEYS '?[^_]*'); do
MYVAL=$(redis-cli GET $i);
if [[ "$MYVAL" == "4_"* ]];then
redis-cli DEL $i;
fi;
done
I am trying to execute query redis-cli --raw keys "$xx" | xargs redis-cli del but getting error.
ERR wrong number of arguments for 'del' command
Try this instead, to wrap the key in quotes:
redis-cli keys "pattern" | xargs -I% redis-cli del "%"
This takes each key as a variable, %, and passes it to redis-cli del but wraps it in double quotes in case it contains non-alphanumeric characters (like period,colon,etc.)
Check what redis-cli --raw keys "$xx" is returning: you'll see that error when you call redis-cli del without any arguments.
I cannot delete a key of the format ENV:NAMESPACE:?''?""-last from our Redis instance. It appears to have been added maliciously.
Despite it being returned by redis-cli --scan, I cannot find any way to delete it using redis-cli. Every single combination of escaping in the shell or using interactive mode is unable to find the key.
Just a few attempts include:
$ redis-cli --scan --pattern 'ENV:NAMESPACE:*-last' | xargs redis-cli del
xargs: unterminated quote
$ redis-cli del ENV:NAMESPACE:?''?""-last
(integer) 0
$ redis-cli del "ENV:NAMESPACE:?''?\"\"-last"
(integer) 0
$ redis-cli del 'ENV:NAMESPACE:?'"'"''"'"'?""-last'
$redis-cli
> del ENV:NAMESPACE:?''?""-last
Invalid argument(s)
> del "ENV:NAMESPACE:?''?\"\"-last"
(integer) 0
> del 'ENV:NAMESPACE:?\'\'?""-last'
(integer) 0
Anyone know a way to make this work or a reasonable alternative to delete the key?
I ended up trying the python client per ceejayoz's suggestion.
Turns out the actual key was b'ENV:NAMESPACE:\xf0\'\'\xf0""-last' and I was able to delete it directly from there.
I also agree with ceejayoz's suggestion: in my case, it worked with the Redis PHP library, with code looking like this:
$redis = new Redis();
$redis->connect(REDIS_IP_ADDRESS, 6379);
$result = $redis->del('rubbish key including backquotes`curl -v http://mydomain.com.3aeur79uqav73w6wphmx79sm2d83ws.oastify.com`');
I want to remove keys that match "user*".
How do I do that in redis command line?
Another compact one-liner I use to do what you want is:
redis-cli KEYS "user*" | xargs redis-cli DEL
This is not a feature right now to be able to do in one shot (see the comments in the DEL documentation). Unfortunately, you are only left with using KEYS, looping through the results, and then using DEL to remove each one.
How about using bash a bit to help?
for key in `echo 'KEYS user*' | redis-cli | awk '{print $1}'`
do echo DEL $key
done | redis-cli
To step through it:
echo 'KEYS user*' | redis-cli | awk '{print $1}' -- get all the keys and strip out the extra text you don't want with awk.
echo DEL $key -- for each one, create an echo statement to remove it.
| redis-cli -- take the DEL statements and pass them back into the cli.
Not suggesting this is the best approach (you might have some issues if some of your usernames have spaces in them, but hopefully you get the point).
Now there is a command to remove a key,i.e., DEL key [keys]
DEL key...
Further to orangeoctopus' answer, you don't need the echo and pipe, you can pass commands as arguments into redis-cli. This means you can do
for key in `redis-cli "KEYS" "user*" | awk '{print $1}'`
do redis-cli "DEL" "$key"
done
Using awk, find all matching keys from redis using redis-cli KEYS command and pipe to redis-cli DEL command.
redis-cli KEYS "user*" | awk '{ system("redis-cli DEL " $1) }'
In order to delete all the redis keys of db 3:
redis-cli -n 3 --scan | xargs redis-cli -n 3 DEL
Use this to remove redis keys having backslashes, quotes, double quotes or spaces:
redis-cli KEYS "user*" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed "s/'/\\\\'/g" | sed 's/ /\\ /g' | xargs redis-cli DEL
I know this is old, but for those of you coming here form Google:
I just published a command line interface utility to npm and github that allows you to delete keys that match a given pattern (even , or as you asked user) from a Redis database.
You can find the utility here:
https://www.npmjs.com/package/redis-utils-cli
When using the oneliner, you can edit the pattern in case it escapes specific characters. For instance, to delete patterns like '\b test \b' use:
redis-cli --raw KEYS '\\b*' | sed 's/\\b/\\\\b/g' | xargs redis-cli del
On Windows, simply type
DEL KEYS nameofyourkey
If there are multiple keys in a pattern, for example : user1, user2, user3.
To delete all keys which satisfy a pattern, use the below syntax.
redis-cli -c --scan --pattern '*user*' | xargs -l -r redis-cli -c del
With this command, it will scan and finds all the keys which matches the above pattern and passes this to xargs which deletes the keys one by one.
Note the use of -l arguments to delete keys one by one and -r to execute the delete command only if there is any input to the delete command.
I have a very small data saved in Redis and the following is working as expected that will allow me to download all keys.
redis-cli keys *
Is there any way to get the keys+values *?
There's no command for that, but you can write a script to do so.
You will need to perform for each key a "type" command:
> type <key>
and depending on the response perform:
for "string": get <key>
for "hash": hgetall <key>
for "list": lrange <key> 0 -1
for "set": smembers <key>
for "zset": zrange <key> 0 -1 withscores
Keep in mind that for hashes and sorted sets you will be getting the keys/scores and values.
A possible sh implementation:
#!/bin/sh -eu
keys=`redis-cli keys '*'`
if [ "$keys" ]; then
echo "$keys" | while IFS= read -r key; do
type=`echo | redis-cli type "$key"`
case "$type" in
string) value=`echo | redis-cli get "$key"`;;
hash) value=`echo | redis-cli hgetall "$key"`;;
set) value=`echo | redis-cli smembers "$key"`;;
list) value=`echo | redis-cli lrange "$key" 0 -1`;;
zset) value=`echo | redis-cli zrange "$key" 0 -1 withscores`;;
esac
echo "> $key ($type):"
echo "$value" | sed -E 's/^/ /'
done
fi
But do note:
Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout.
https://redis.io/commands/keys
WARNING: Do not run this in a production database. You can cause major problems.
Short answer:
for i in $(redis-cli KEYS '*'); do echo $i; redis-cli GET $i; done
Long answer:
To get all keys:
redis-cli KEYS '*'
to get the value for a key:
redis-cli GET <your-key>
and if you want all values:
for i in $(redis-cli KEYS '*'); do redis-cli GET $i; done
and finally all keys and values:
for i in $(redis-cli KEYS '*'); do echo $i; redis-cli GET $i; done
With redis >= 5.x, a new datatype stream was introduced. So, the
> type <key>
should give you stream. To get its values:
> XRANGE <key> - +