如何在 Linux 上判断 Bash 字符串是否包含子字符串
已发表: 2022-09-21
有时在 Linux 脚本中,您想知道文本字符串是否包含特定的较小字符串。 有很多方法可以做到这一点。 我们向您展示了一些简单、可靠的技术。
为什么这有用?
在字符串中搜索较小的子字符串是一项常见要求。 一个示例是从文件或人工输入中读取文本并在字符串中搜索特定子字符串,以便您的脚本可以决定下一步该做什么。 它可能会在配置文件中查找标签或设备名称,或者在用户的输入行中查找命令字符串。
Linux 用户有幸拥有许多用于处理文本的实用程序。 有些内置在 Bash shell 中,有些则作为独立的实用程序或应用程序提供。 Unix 衍生的操作系统提供丰富的字符串操作功能是有原因的。
有些看起来是文件的东西并不是简单的文件。 它们是表示硬件设备和系统信息来源等内容的特殊文件。 操作系统执行的抽象赋予它们文件的外观和特征。 您可以从它们中读取信息——自然是文本——并且在某些情况下写入它们,但它们不是普通文件。
文本还用作终端窗口中命令的输入和输出。 这允许输入和输出的重定向和管道。 该功能支持将 Linux 命令序列链接在一起的能力,将一个命令的输出作为输入传递给下一个命令。
无论其来源如何,在我们收到的文本中搜索重要的单词、命令、标签或其他指示符是处理基于文本的数据的标准部分。 以下是您可以在自己的脚本中包含的一系列简单技术。
使用 Bash Builtins 查找子字符串
双括号“ [[...]]
”字符串比较测试可用于if
语句中,以确定一个字符串是否包含另一个字符串。
将此脚本复制到编辑器中,并将其保存到名为“double.sh”的文件中。
#!/bin/bash 如果 [[ “猴子” = *“钥匙”* ]]; 然后 echo "钥匙在猴子里" 别的 echo "key不在monkey中" 菲
您需要使用chmod
命令使脚本可执行。 这是使任何脚本可执行的始终必需的步骤。 每次创建脚本文件时都需要这样做。 在每种情况下替换相应脚本的名称。
chmod +x 双倍.sh
让我们运行脚本。
./double.sh
这是因为星号“ *
”代表任何字符序列,包括无字符。 如果子字符串“key”位于目标字符串中,无论其前后是否有任何字符,测试都将返回 true。
在我们的示例中,子字符串前面有字符。 这些由第一个星号匹配。 子字符串后面没有字母,但是,因为星号也不匹配任何字符,所以测试仍然通过。
为了灵活性,我们可以修改我们的脚本来处理变量而不是文字字符串。 这是脚本“double2.sh”。
#!/bin/bash 字符串="猴子" 子串=“键” 如果 [[ $string = *$substring* ]]; 然后 echo "$substring 在 $string 中找到" 别的 echo "$substring 在 $string 中没有找到" 菲
让我们看看它是如何运行的。
./double2.sh
这以相同的方式工作,优点是我们可以使用变量名而不是文字字符串。 将我们的小解决方案变成一个函数将提供最大的灵活性。
这是脚本“double3.sh”。
#!/bin/bash shopt -s nocasematch 字符串="猴子" 子串=“键” 首都=“伦敦” check_substring () { 如果 [[ $1 = *$2* ]]; 然后 echo "在 $1 中找到 $2" 别的 echo "$1 中未找到 $2" 菲 } check_substring "猴子" "钥匙" check_substring $string $substring check_substring $string "香蕉" check_substring "威尔士" $capital
我们使用变量和文字字符串的混合来调用我们的check_substring
函数。 我们使用shopt
及其-s
(set) 选项来设置nocasematch
,以使匹配不区分大小写。
这是它的运行方式。
./double3.sh

我们也可以在case
语句中使用将子字符串包装在星号中的技巧。 这是“case.sh”。
#!/bin/bash shopt -s nocasematch 字符串="小袋鼠" 子串=“墙” 案例$字符串在 *$子字符串*) echo "$substring 在 $string 中找到" ;; *) echo "没有匹配:$string" ;; 经社理事会
使用case
语句而不是很长的if
语句可以使脚本更易于阅读和调试。 如果您需要检查一个字符串是否包含许多可能的子字符串之一,那么case
语句将是最佳选择。
./case.sh
找到子字符串。
使用 grep 查找子字符串
除了 Bash 内置程序之外,您可能会使用的第一个文本搜索工具是grep
。 我们可以使用grep
在字符串中搜索字符串的先天能力来查找我们的子字符串。
该脚本称为“subgrep.sh”。
#!/bin/bash string="粥锅" 子串="山脊" if $(echo $string | grep -q $substring); 然后 echo "$substring 在 $string 中找到" 别的 echo "$substring 在 $string 中没有找到" 菲
该脚本使用echo
将字符串发送到grep
,后者搜索子字符串。 我们使用-q
(安静)选项来停止grep
将任何内容写入标准输出。
如果括号“ (...)
”内的命令结果为零,则表示找到了匹配项。 因为在 Bash 中零等于true
,所以满足if
语句并执行then
子句。
让我们看看它的输出是什么。
./subgrep.sh
使用 sed 查找子字符串
我们也可以使用sed
来查找子字符串。
默认情况下, sed
会打印输入其中的所有文本。 使用sed -n
可以防止这种情况。 唯一打印的行是匹配行。 此表达式将打印任何匹配或包含 $substring 值的行。
"/$substring/p"
我们使用这里的重定向将$string
的值输入到sed
中, <<<
。 这用于将值重定向到当前 shell 中的命令。 它不会像管道那样调用子shell。
第一个-n
是测试。 如果sed
命令的输出非零,它将返回true
。 sed
的输出可以是非零的唯一方法是找到匹配的行。 如果是这种情况,则必须在$string
中找到$substring
。
这是“subsed.sh”。
#!/bin/bash 字符串="瑞典" 子串=“伊甸园” if [ -n "$(sed -n "/$substring/p" <<< $string)" ]; 然后 echo "$substring 在 $string 中找到" 别的 echo "$substring 在 $string 中没有找到" 菲
当我们运行脚本时,我们得到了预期的响应。
./subsed.sh
我们可以通过编辑$substring
的值来测试脚本的逻辑,这样比较失败。
./subsed.sh
停止搜索,找到它
其他工具可以找到子字符串,例如awk
和Perl
,但是像查找子字符串这样的简单用例并不能保证它们的额外功能或增加的复杂性。 特别是,使用 Bash 内置搜索子字符串快速、简单且不需要外部工具。
相关:如何在 Bash 脚本中使用案例语句