为什么这有用?
在字符串中搜索较小的子字符串是一项常见要求。一个示例是从文件或人工输入中读取文本并在字符串中搜索特定子字符串,以便您的脚本可以决定下一步该做什么。它可能会在配置文件中查找标签或设备名称,或者在用户的输入行中查找命令字符串。
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
(quiet) 选项停止grep
向标准输出写入任何内容。
如果括号“ ”内的命令结果(...)
为零,则表示找到了匹配项。true
因为在 Bash 中,零等于,所以if
满足语句并then
执行子句。
让我们看看它的输出是什么。
./subgrep.sh
使用 sed 查找子字符串
我们也可以使用它sed
来查找子字符串。
默认情况下,sed
打印输入其中的所有文本。使用sed -n
可以防止这种情况。唯一打印的行是匹配行。此表达式将打印任何匹配或包含 $substring 值的行。
"/$substring/p"
我们将 的值$string
输入到sed
使用此处的重定向中,<<<
. 这用于将值重定向到当前 shell 中的命令。它不会像管道那样调用子shell。
首先-n
是测试。true
如果命令的输出sed
非零,它将返回。输出sed
非零的唯一方法是找到匹配的行。如果是这样的话,$substring
一定是在$string
.
这是“subsed.sh”。
#!/bin/bash
字符串="瑞典"
子串=“伊甸园”
if [ -n "$(sed -n "/$substring/p" <<< $string)" ]; 然后
echo "$substring 在 $string 中找到"
别的
echo "$substring 在 $string 中没有找到"
是
当我们运行脚本时,我们得到了预期的响应。
./subsed.sh
我们可以通过编辑 的值来测试脚本的逻辑,$substring
从而使比较失败。
./subsed.sh
停止搜索,找到它
其他工具可以找到子字符串,例如awk
andPerl
但是像查找子字符串这样的简单用例并不能保证它们的额外功能或增加的复杂性。特别是,使用 Bash 内置搜索子字符串快速、简单且不需要外部工具。