Bash string operation

Shell脚本基础教程

11. Tables

11.1 String comparison operators

(1) s1 = s2

(2) s1 != s2

(3) s1 < s2

(4) s1 > s2

(5) -n s1

(6) -z s1

(1) s1 matches s2

(2) s1 does not match s2

(3) __TO-DO__

(4) __TO-DO__

(5) s1 is not null (contains one or more characters)

(6) s1 is null

11.2 String comparison examples

Comparing two strings.

        #!/bin/bash
        S1='string'
        S2='String'
        if [ $S1=$S2 ];
        then
                echo "S1('$S1') is not equal to S2('$S2')"
        fi
        if [ $S1=$S1 ];
        then
                echo "S1('$S1') is equal to S1('$S1')"
        fi
        

I quote here a note from a mail, sent buy Andreas Beck, refering to use if [ $1 = $2 ].

This is not quite a good idea, as if either $S1 or $S2 is empty, you will get a parse error. x$1=x$2 or "$1"="$2" is better.

11.3 Arithmetic operators

+

-

*

/

% (remainder)

11.4 Arithmetic relational operators

-lt (<)

-gt (>)

-le (<=)

-ge (>=)

-eq (==)

-ne (!=)

C programmer's should simple map the operator to its corresponding parenthesis.

11.5 Useful commands

This section was re-written by Kees (see thank to...)

Some of these command's almost contain complete programming languages. From those commands only the basics will be explained. For a more detailed description, have a closer look at the man pages of each command.

sed (stream editor)

Sed is a non-interactive editor. Instead of altering a file by moving the cursor on the screen, you use a script of editing instructions to sed, plus the name of the file to edit. You can also describe sed as a filter. Let's have a look at some examples:

        $sed 's/to_be_replaced/replaced/g' /tmp/dummy
        

Sed replaces the string 'to_be_replaced' with the string 'replaced' and reads from the /tmp/dummy file. The result will be sent to stdout (normally the console) but you can also add '> capture' to the end of the line above so that sed sends the output to the file 'capture'.

        $sed 12, 18d /tmp/dummy
        

Sed shows all lines except lines 12 to 18. The original file is not altered by this command.

awk (manipulation of datafiles, text retrieval and processing)

Many implementations of the AWK programming language exist (most known interpreters are GNU's gawk and 'new awk' mawk.) The principle is simple: AWK scans for a pattern, and for every matching pattern a action will be performed.

Again, I've created a dummy file containing the following lines:

"test123

test

tteesstt"

        $awk '/test/ {print}' /tmp/dummy
        

test123

test

The pattern AWK looks for is 'test' and the action it performs when it found a line in the file /tmp/dummy with the string 'test' is 'print'.

        $awk '/test/ {i=i+1} END {print i}' /tmp/dummy
        

3

When you're searching for many patterns, you should replace the text between the quotes with '-f file.awk' so you can put all patterns and actions in 'file.awk'.

grep (print lines matching a search pattern)

We've already seen quite a few grep commands in the previous chapters, that display the lines matching a pattern. But grep can do more.

        $grep "look for this" /var/log/messages -c
        

12

The string "look for this" has been found 12 times in the file /var/log/messages.

[ok, this example was a fake, the /var/log/messages was tweaked :-)]

wc (counts lines, words and bytes)

In the following example, we see that the output is not what we expected. The dummy file, as used in this example, contains the following text: "bash introduction howto test file"

        $wc --words --lines --bytes /tmp/dummy
        

2 5 34 /tmp/dummy

Wc doesn't care about the parameter order. Wc always prints them in a standard order, which is, as you can see: .

sort (sort lines of text files)

This time the dummy file contains the following text:

"b

c

a"

        $sort /tmp/dummy
        

This is what the output looks like:

a

b

c

Commands shouldn't be that easy :-) bc (a calculator programming language)

Bc is accepting calculations from command line (input from file. not from redirector or pipe), but also from a user interface. The following demonstration shows some of the commands. Note that

I start bc using the -q parameter to avoid a welcome message.

   $bc -q
        

1 == 5

0

0.05 == 0.05

1

5 != 5

0

2 ^ 8

256

sqrt(9)

3

while (i != 9) {

i = i + 1;

print i

}

123456789

quit

tput (initialize a terminal or query terminfo database)

A little demonstration of tput's capabilities:

        $tput cup 10 4
        

The prompt appears at (y10,x4).

        $tput reset
        

Clears screen and prompt appears at (y1,x1). Note that (y0,x0) is the upper left corner.

        $tput cols
        
80

Shows the number of characters possible in x direction.

It it higly recommended to be familiarized with these programs (at least). There are tons of little programs that will let you do real magic on the command line.

[some samples are taken from man pages or FAQs]


Next   Previous   Contents
<think>嗯,用户现在问的是关于Redis的错误信息“operation against a key holding”,不过看起来用户可能输入有误,正确的错误应该是“operation against a key holding the wrong kind of value”。我需要先确认这一点,然后给出相应的解释和解决方法。 首先,我得回想一下Redis中常见的错误类型。当用户尝试对某个键执行不兼容的操作时,比如对字符串类型的键使用列表的操作命令,这时候Redis会返回这个错误。比如,用户可能用LPUSH命令去操作一个原本是字符串类型的键,这时候就会报错。所以,这个错误的核心原因是数据类型不匹配。 接下来,我需要考虑用户为什么会遇到这个问题。可能的场景包括:用户误用了命令,或者键的类型被意外修改,或者在多线程/多客户端环境下,不同的操作覆盖了键的数据类型。比如,一个客户端设置了键为字符串,另一个客户端却尝试将其作为列表来操作。 然后,我需要整理解决这个问题的步骤。首先,用户需要确认键的当前类型,可以使用TYPE命令。接着,检查正在使用的命令是否与该类型兼容。如果不兼容,用户需要决定是修改命令还是删除/覆盖该键。如果是并发问题,可能需要使用事务或WATCH命令来保证数据一致性。 此外,可能还需要提供一些示例,帮助用户更好地理解。比如,演示如何正确使用命令,或者如何处理类型冲突的情况。同时,提醒用户在设计数据结构时提前规划,避免类型错误,以及使用DEBUG OBJECT命令来获取更多信息。 还需要注意用户可能的其他需求,比如如何批量检查键的类型,或者如何自动化处理这类错误。不过,根据用户当前的问题,可能不需要深入这些高级话题,但可以简要提及作为扩展。 最后,总结一下解决步骤,确保用户能够按照清晰的流程排查和解决问题。同时,强调预防措施,比如合理设计数据结构和进行类型检查,以避免未来出现类似问题。</think>在 Redis 中遇到错误 `WRONGTYPE Operation against a key holding the wrong kind of value` 时,表示**尝试对某个键执行了与其数据类型不兼容的操作**。以下是详细解析与解决方法: --- ### 一、错误原因 Redis 的键值对具有明确的数据类型(如字符串、列表、哈希等),**不同数据类型的操作命令不可混用**。例如: - 对字符串键尝试执行列表操作(如 `LPUSH`) - 对哈希键尝试执行集合操作(如 `SADD`) - 对已过期的键执行写操作(需注意过期逻辑) **典型报错示例**: ```bash 127.0.0.1:6379> SET mykey "hello" OK 127.0.0.1:6379> LPUSH mykey "world" (error) WRONGTYPE Operation against a key holding the wrong kind of value ``` --- ### 二、解决步骤 #### 1. 确认键的当前数据类型 使用 `TYPE` 命令检查键的实际类型: ```bash TYPE mykey # 返回结果可能是:string, list, hash, set, zset, stream 等 ``` #### 2. 检查操作命令与数据类型是否匹配 | 数据类型 | 支持的命令示例 | 不兼容操作示例 | |----------|-----------------------------------|--------------------------------| | **String** | `GET`, `SET`, `INCR` | `LPUSH`, `HSET`, `SADD` | | **List** | `LPUSH`, `RPOP`, `LRANGE` | `SADD`, `HGET`, `ZADD` | | **Hash** | `HSET`, `HGET`, `HKEYS` | `LPUSH`, `SISMEMBER`, `ZRANGE` | | **Set** | `SADD`, `SMEMBERS`, `SINTER` | `HGET`, `ZADD`, `LPOP` | | **ZSet** | `ZADD`, `ZRANGE`, `ZSCORE` | `HGETALL`, `SADD`, `LPUSH` | #### 3. 修复方案 - **方案 1:改用兼容命令** 根据键的实际类型调整操作命令。例如,若键是字符串类型,需改用 `GET/SET` 而非列表操作。 - **方案 2:删除并重建键** 若需强制变更键的类型,先删除旧键再重建: ```bash DEL mykey # 删除旧键 LPUSH mykey "a" # 重新创建为列表类型 ``` - **方案 3:检查并发冲突** 若键类型被其他客户端意外修改,需排查多线程/多客户端操作,或使用 `WATCH` 命令实现原子性操作: ```bash WATCH mykey # 监控键变化 MULTI # 开启事务 TYPE mykey # 确认类型 LPUSH mykey "b" # 执行操作 EXEC # 提交事务(若类型未变化则成功) ``` --- ### 三、高级调试技巧 #### 1. 批量检查键类型 使用 `SCAN` 命令遍历键并批量检查类型: ```bash # 查找所有字符串类型的键 SCAN 0 MATCH * COUNT 1000 TYPE string ``` #### 2. 查看键的详细编码 通过 `OBJECT ENCODING` 了解底层存储结构(如 `int`, `embstr`, `hashtable` 等): ```bash OBJECT ENCODING mykey ``` #### 3. 监控键变更 使用 `MONITOR` 命令实时观察键的操作来源(谨慎使用,仅限调试): ```bash MONITOR # 观察是否有其他客户端修改了键类型 ``` --- ### 四、预防措施 1. **规范键命名** 在键名中标注类型,如 `user:1001:string`, `order:2002:hash`。 2. **操作前显式检查类型** 在代码中添加类型验证逻辑: ```python # Python 示例(redis-py) if redis_client.type("mykey") == b'list': redis_client.lpush("mykey", "value") else: handle_error() ``` 3. **使用 Lua 脚本保证原子性** 通过脚本确保类型检查和操作在原子环境下完成: ```lua -- 示例:仅当键为列表时才执行 LPUSH if redis.call("TYPE", KEYS[1]) == "list" then return redis.call("LPUSH", KEYS[1], ARGV[1]) else return nil end ``` --- ### 五、典型场景案例 #### 案例 1:误用哈希命令操作字符串键 **错误操作**: ```bash 127.0.0.1:6379> SET user:1001 "Alice" OK 127.0.0.1:6379> HGET user:1001 name (error) WRONGTYPE Operation against a key holding the wrong kind of value ``` **修复**: ```bash # 正确做法:使用哈希结构存储字段 HSET user:1001 name "Alice" HGET user:1001 name ``` #### 案例 2:过期键未及时清理导致类型冲突 若键因过期被自动删除,但未更新客户端缓存,可能导致后续操作仍尝试使用旧类型。 --- 通过以上方法可快速定位并解决 Redis 数据类型冲突问题,同时通过规范设计和原子性操作避免未来出现类似错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值