在Bash中如何检查字符串是否包含子字符串

文章讨论了在Bashshell中检查字符串是否包含特定子串的不同方法,包括if语句、case语句、正则表达式以及创建自定义函数,同时给出了相应的示例和参考链接。

问:

在 Bash 中一个字符串如下:

string="My string"

如何测试它是否包含另一个字符串?

if [ $string ?? 'foo' ]; then
  echo "It's there!"
fi

其中 ?? 是我不知道的运算符。我该使用 echo 和 grep 吗?

if echo "$string" | grep 'foo'; then
  echo "It's there!"
fi

这看起来有点笨拙。


答1:

我不确定是否可以使用 if 语句,但你可以使用 case 语句得到类似的效果:

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac

答2:

如果使用双方括号,也可以在 case 语句之外使用 Marcus 的答案(* 通配符):

string='My long string'
if [[ $string == *"My long"* ]]; then
  echo "It's there!"
fi

请注意,中间有空格的字符串需要放在双引号之间,* 通配符应该在外面。还要注意,这里使用了一个简单的比较操作符(即 ==),而不是正则表达式操作符 =~


答3:

如果你更喜欢正则表达式的方法:

string='My string';

if [[ $string =~ "My" ]]; then
   echo "It's there!"
fi

更多解决思路的回答参考:https://stackoverflow.com/a/20460402

简单的函数:

stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};}

这样可以测试空字符串的情况:

$ if stringContain '' ''; then echo yes; else echo no; fi
yes
$ if stringContain 'o "M' ''; then echo yes; else echo no; fi
no


参考:stackoverflow question 229551


 相关阅读:

<think>在Makefile中,判断一个字符串是否包含另一个字符串,可以通过使用`findstring`函数和条件判断来实现。`findstring`函数会在第一个参数中查找第二个参数,如果找到则返回第二个参数,否则返回空。然后,我们可以通过判断返回值是否为空来确定是否包含子字符串。 ### 解决方案步骤: 1. **使用`findstring`函数**:`$(findstring 子字符串, 源字符串)` 2. **与条件语句结合**:使用`if`条件判断`findstring`的结果是否等于子字符串(即不为空)。 ### 示例Makefile代码: ```makefile # 定义源字符串 SOURCE_STRING = "hello world" # 定义要查找的子字符串 SUBSTRING = "world" # 检查SOURCE_STRING是否包含SUBSTRING ifneq ($(findstring $(SUBSTRING),$(SOURCE_STRING)),) # 如果包含,则执行这里的命令 $(info The string contains the substring) else # 如果不包含,则执行这里的命令 $(info The string does not contain the substring) endif all: @echo "Done." ``` ### 代码解释: - `findstring $(SUBSTRING),$(SOURCE_STRING)`:在`SOURCE_STRING`中查找`SUBSTRING`,如果找到则返回`SUBSTRING`,否则返回空。 - `ifneq (A, B)`:如果A不等于B,则条件成立。这里我们判断`findstring`的结果是否不等于空(即不为空),如果不为空,则说明包含子字符串。 ### 注意事项: 1. **大小写敏感**:`findstring`是大小写敏感的。例如,在"Hello World"中查找"world"将不会匹配。 2. **空格处理**:在Makefile中,字符串中的空格会被保留。确保在定义字符串时,如果字符串包含空格,使用引号(如`SOURCE_STRING = "hello world"`)或者直接写(如`SOURCE_STRING = hello world`,但注意这样定义时,变量值就是`hello world`,没有引号)。 3. **条件语句的位置**:上述条件语句(`ifneq`...`endif`)必须放在规则外部(全局作用域)或者规则内部。如果放在全局作用域,它会在Makefile解析时立即执行;如果放在规则内部,则会在规则执行时执行。 4. **使用`$(info ...)`**:这里使用`$(info ...)`来打印信息,它会在Makefile解析时输出。如果你想在规则执行时输出,可以使用`@echo`。 ### 变体:在规则内部进行判断 如果你希望在一个规则内部进行判断,可以这样写: ```makefile SOURCE_STRING = "hello world" SUBSTRING = "world" all: @if [ -n "$(findstring $(SUBSTRING),$(SOURCE_STRING))" ]; then \ echo "The string contains the substring"; \ else \ echo "The string does not contain the substring"; \ fi ``` 这里使用了shell的条件判断,因为Makefile的`findstring`函数在规则内部也可以使用,但条件语句需要转换为shell语法。 ### 相关问题: 1. 在Makefile中,如何忽略大小写进行子字符串查找? 2. 如何在Makefile中判断一个字符串是否以特定子字符串开头或结尾? 3. 在Makefile中,如何同时检查多个子字符串是否存在?</think>在 Makefile 中检查字符串是否包含子字符串,可以使用 GNU Make 内置的 `findstring` 函数结合条件判断语句。以下是详细实现方法: ### 解决方案:使用 `findstring` 函数 ```makefile # 定义源字符串子字符串 STRING_A = "hello world" SUBSTRING_B = "world" # 检查是否包含子字符串 ifneq ($(findstring $(SUBSTRING_B),$(STRING_A)),) $(info 字符串包含子字符串) else $(info 字符串包含子字符串) endif all: @echo "构建完成" ``` ### 代码解释: 1. **`findstring` 函数**: - 语法:`$(findstring 查找内容, 源字符串)` - 如果找到子串,返回子串内容;否则返回空字符串 - 示例:`$(findstring world,hello world)` → 返回 `"world"` 2. **`ifneq` 条件判断**: - `ifneq (A,B)` 检查 A 是否不等于 B - 这里检查 `findstring` 结果是否不等于空:`ifneq ($(findstring...),)` 3. **`$(info)` 函数**: - 在 Makefile 解析阶段输出信息 - 替代方案:在规则中使用 `@echo`(执行阶段输出) ### 完整示例(包含多个子串检查): ```makefile STRING_A = "The quick brown fox jumps" SUB_B = "brown" SUB_C = "dog" # 检查是否同时包含 B 和 C ifneq ($(findstring $(SUB_B),$(STRING_A)),) ifneq ($(findstring $(SUB_C),$(STRING_A)),) $(info 字符串同时包含 B 和 C) else $(info 字符串包含 B 但不包含 C) endif else $(info 字符串包含 B) endif check: @echo "检查完成" ``` ### 使用说明: 1. **执行效果**: ```bash $ make 字符串包含 B 但不包含 C 构建完成 $ make check 检查完成 ``` 2. **重要特性**: - **大小写敏感**:`findstring` 区分大小写 - **空格处理**:源字符串中的空格会被保留 - **特殊字符**:支持 `*`、`?` 等通配符(需转义) - **执行阶段**:`$(findstring)` 在 Makefile 解析阶段执行 ### 变体:在规则内部检查 ```makefile check: @if [ -n "$(findstring $(SUB_B),$(STRING_A))" ]; then \ echo "包含子串"; \ else \ echo "不包含子串"; \ fi ``` ### 注意事项: 1. 当子字符串为空时,`findstring` 总是返回非空结果 2. 使用引号包裹含空格的字符串:`"multiple words"` 3. 对于复杂匹配,可结合 `filter` 函数: ```makefile # 检查是否以特定子串开头 ifeq ($(filter $(SUB_B)%,$(STRING_A)),$(STRING_A)) $(info 以 $(SUB_B) 开头) endif ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值