我试图在shell脚本中比较两个“几乎”相同的字符串。除了一个字符(A-Z)之外,它们都很相似。在下面的示例中,我希望代码对字符串从1-2-3-A-5-6-
到1-2-3-Z-5-6-
的所有大小写都返回true
目前我的代码返回false。
#!/bin/bash
TEMPLATE='1-2-3-*-5-6-'
CASE='1-2-3-A-5-6-'
if [[ "$TEMPLATE" == "$CASE" ]]; then
echo "It's there."
else
echo "NO, improve!"
fi
2条答案
按热度按时间b4wnujal1#
模式
1-2-3-*-5-6-
是一个 glob。这种模式语言在bash手册的Pattern Matching部分中有描述,并且可用于您尝试使用的
[[ == ]]
测试(下面引用的手册)和注解中提到的case
版本。表情
...使用
==
和!=
运算符时,运算符右侧的字符串被视为模式,并根据下面模式匹配下描述的规则进行匹配,就像启用了extglob shell选项一样。=
运算符等效于==
。如果启用了nocase‐ match shell选项,执行匹配而不考虑字母字符的大小写。...模式的任何部分都可以用括起来,以强制括起来的部分作为字符串进行匹配。
只有两个约束条件:
1.如果希望模式作为模式而不是文本字符串进行匹配,则不能用引号将其括起来
(see最后引用的段落)
1.图案必须位于操作员的右手侧
(第一段)
所以你的代码可以正常工作
注意:使用内置的
[[ ]]
条件而不是旧的[ ]
条件的部分原因是不对
[[
和]];
之间的字执行字拆分和路径名扩展所以通常不需要给变量加引号(在这个特定的例子中,* 不能 * 至少给其中一个变量加引号)。
uurv41yg2#
就像这样。
或者,您可以直接在赋值语句中添加glob/pattern
[A-Z]
,而不是glob*
。接受的答案已经解释了OP代码的直接错误/问题。只是想添加
set -x
中的一小段代码,以支持为什么您不需要引用=
或==
的rhs Right Hand Side(如果目的是进行模式匹配)。引用
==
或=
甚至=~
操作符的RHS将使它成为一个文本字符串而不是模式/glob/regex,因为每个字符串都有一个前导\
,而\
是引用/转义shell的一种形式。