如何在字符串中查找子字符串(或如何 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
【问题讨论】:
如果不知道LIST
和SOURCE
是什么样子,就很难回答任何类型的问题
在 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 扫描整个目录来在文件内容中查找具有特定字符串的文件 [重复]