演出迟到了?下面的非常简单的变体还没有明确提到。我用case检查简单的列表,这是一个不依赖任何外部或扩展的Bourne Shell成语:
haystack='a b c'
needle='b'
case " $haystack " in (*" $needle "*) :;; (*) false;; esac
Please note the use of the separator (here: SPC) to correcyly delimit the pattern: At the beginning and end of " $haystack " and likewise in the test of " $needle ".
This statement returns true ($?=0) in case $needle is in $haystack, false otherwise.
Also you can test for more than one $needle very easily. When there are several similar cases like
if (haystack.contains(needle1)) { run1() } elif (haystack.contains(needle2)) { run2() } else { run3() }
you can wrap this into the case, too:
case " $haystack " in (*" $needle1 "*) run1;; (*" $needle2 "*) run2;; (*) run3;; esac
and so on
这也适用于所有值不包括分隔符本身的列表,比如逗号:
haystack=' a , b , c '
needle=' b '
case ",$haystack," in (*",$needle,"*) :;; (*) false;; esac
请注意,如果值可以包含包括分隔符序列的任何内容(除了NUL,因为shell不支持变量中的NUL,因为您不能将包含NUL的参数传递给命令),那么您需要使用数组。数组是ksh/bashisms,不受“普通”POSIX/Bourne shell的支持。(你可以在posix - shell中使用$@来解决这个限制,但这与这里完全不同。)
错误的部分可以去掉吗?
不,因为这是临界返回值。默认情况下,case返回true。
如果你不需要返回值并将你的处理放在:
为什么:;;
我们也可以写成true;;,但我习惯用:而不是true,因为这样打字更短更快
另外,我认为不写任何不好的做法,因为对于每个人来说,case的默认返回值是true并不明显。
此外,“leaving out”这个命令通常表示“这里忘记了一些东西”。因此,在这里放一个多余的“:”清楚地表明“它的目的只是在这里返回true”。
在bash中,您还可以使用ksh/bashisms,如;& (fallthrough)或;;&(测试其他模式)来表示if (hastack .contains(needle1)) {run1();};If (hastack .contains(needle2)) {run2();}
因此,case通常比其他正则表达式结构更易于维护。此外,它不使用正则表达式,它只使用shell模式,这甚至可能更快。
可重用的功能:
: Needle "list" Seperator_opt
NeedleListSep()
{
if [ 3 -gt $# ];
then NeedleListSep "$1" "$2" " ";
else case "$3$2$3" in (*"$3$1$3"*) return 0;; esac; return 1;
fi;
}
在bash中,您可以将其简化为
: Needle "list" Seperator_opt
NeedleListSep()
{
local s="${3-" "}";
case "$s$2$s" in (*"$s$1$s"*) return 0;; esac; return 1;
}
像这样使用
Test() {
NeedleListSep "$1" "a b c" && echo found $1 || echo no $1;
NeedleListSep "$1" "a,b,c" ',' && echo found $1 || echo no $1;
NeedleListSep "$1" "a # b # c" ' # ' && echo found $1 || echo no $1;
NeedleListSep "$1" "abc" '' && echo found $1 || echo no $1;
}
Test a
Test z
如上所示,这也适用于分隔符为空字符串的退化情况(因此列表中的每个字符都是针)。例子:
Test
返回
no
no
no
found
因为空字符串是abc的清晰部分如果分隔符是空字符串,对吧?
请注意,这个函数是公共领域的,因为它绝对没有任何东西可以真正获得版权。