如何在字符串中查找子字符串(或如何 grep 变量)? [复制]

Posted

技术标签:

【中文标题】如何在字符串中查找子字符串(或如何 grep 变量)? [复制]【英文标题】:How to find substring inside a string (or how to grep a variable)? [duplicate] 【发布时间】:2011-05-26 22:44:16 【问题描述】:

我正在使用 BASH,但我不知道如何找到子字符串。它一直失败,我有一个字符串(这应该是一个数组吗?)

下面,LIST 是数据库名称的字符串列表,SOURCE 是回复,其中一个数据库。以下仍然不起作用:

echo "******************************************************************"
echo "*                  DB2 Offline Backup Script                     *"
echo "******************************************************************"
echo "What's the name of of the  database you would like to backup?"
echo "It will be named one in this list:"
echo ""
LIST=`db2 list database directory | grep "Database alias" | awk 'print $4'`
echo $LIST
echo ""
echo "******************************************************************"
echo -n ">>> "
read -e SOURCE

if expr match "$LIST" "$SOURCE"; then
    echo "match"
    exit -1
else
    echo "no match"
fi
exit -1

我也试过了,但是不行:

if [ `expr match "$LIST" '$SOURCE'` ]; then

【问题讨论】:

如果不知道LISTSOURCE 是什么样子,就很难回答任何类型的问题 在 Bash 中,几乎总是没有理由使用 expr 这是一个外部实用程序。 是的,有人解决了它:***.com/questions/229551/string-contains-in-bash String contains a substring in Bash 的可能重复项。 【参考方案1】:
LIST="some string with a substring you want to match"
SOURCE="substring"
if echo "$LIST" | grep -q "$SOURCE"; then
  echo "matched";
else
  echo "no match";
fi

【讨论】:

使用这种方法需要考虑的 2 个问题: (1) grep 使用正则表达式,因此某些字符会匹配意外或导致错误; (2) 使用 grep (或任何未内置于 bash 的东西)会产生一个运行速度较慢的单独进程(仅在较大规模的情况下才重要)。【参考方案2】:

你也可以用通配符比较:

if [[ "$LIST" == *"$SOURCE"* ]]

【讨论】:

您应该始终引用字符串,例如:if [[ "$list" == *"$source"* ]] 请注意if [[ *"$SOURCE"* == "$LIST$" ]] 是假的。 我已经确认订单很重要/强制 - 所以*"$SOURCE"* 必须是正确的 - 否则总是返回 false - 为什么会有这种行为?【参考方案3】:

这在 Bash 中有效,无需派生外部命令:

function has_substring() 
   [[ "$1" != "$2/$1/" ]]

示例用法:

name="hello/world"
if has_substring "$name" "/"
then
   echo "Indeed, $name contains a slash!"
fi

【讨论】:

此解决方案的优势在于它不依赖任何外部命令或文件描述符(通过重定向或管道)。 请注意,这是使用正则表达式来搜索子字符串(并且还会进行异地替换),因此搜索中的特殊字符(子字符串)可能会导致意外结果。但是如果正则表达式很好,那么为什么不直接进行正则表达式搜索(即不需要替换)?语法示例:if [[ "$string" =~ $substring ]]【参考方案4】:

如果你使用 bash,你可以说

if grep -q "$SOURCE" <<< "$LIST" ; then
    ...
fi

【讨论】:

【参考方案5】:

如果只想查找单个字符,可以使用“索引”,例如:

LIST="server1 server2 server3 server4 server5"
SOURCE="3"
if expr index "$LIST" "$SOURCE"; then
    echo "match"
    exit -1
else
    echo "no match"
fi

输出是:

23
match

【讨论】:

【参考方案6】:
expr match "$LIST" '$SOURCE'

这个函数不起作用,因为这个函数从字符串的开头搜索 $SOURCE,如果找到 else 0,则返回模式 $SOURCE 之后的位置。所以你必须编写另一个代码:

expr match "$LIST" '.*'"$SOURCE" or expr "$LIST" : '.*'"$SOURCE"

表达式 $SOURCE 必须用双引号引起来,以便解析器可以设置替换。单引号不能替代,上面的代码将从 $LIST 的开头搜索文本字符串 $SOURCE。如果您需要字符串的开头减去长度 $SOURCE,例如 $#SOURCE。 你也可以写

expr "$LIST" : ".*\($SOURCE\)"

这个函数只是从 $LIST 中提取 $SOURCE 并返回它。你会得到空字符串。但是他们对双双引号有问题。我不知道如果不使用其他变量它是如何解决的。 这是一个轻量级的解决方案。所以你可以用C写。有现成的函数strstr。 不要使用 expr 索引,所以很有吸引力。但索引搜索不是子字符串,只有第一个字符。

【讨论】:

【参考方案7】:

expr 使用 而不是 [ 而不是在它里面,并且变量只在双引号内展开,所以试试这个:

if expr match "$LIST" "$SOURCE"; then

但我不太清楚 SOURCE 应该代表什么。

看起来您的代码将从标准输入中读取模式,如果它与数据库别名匹配则退出,否则它会回显“ok”。这就是你想要的吗?

【讨论】:

【参考方案8】:

好吧,这样的事情怎么样:

PS3="Select database or <Q> to quit: "
select DB in db1 db2 db3; do
   [ "$REPLY^*" = 'Q' ] && break
   echo "Should backup $DB..."
done

【讨论】:

以上是关于如何在字符串中查找子字符串(或如何 grep 变量)? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在给定字符串中查找子字符串?

如何通过使用 grep 扫描整个目录来在文件内容中查找具有特定字符串的文件 [重复]

如何使用 Find / Grep / Sed 在文件中查找和替换字符串

Linux里如何查找文件内容

linux命令之——grep详解

在 pom.xml 中对变量进行子字符串化