如何让Shell的CASE语句匹配到模式后仍遍历所有后续匹配项?
让Shell的Case语句匹配后继续遍历所有后续模式
嘿,我懂你的需求——默认情况下Shell的case语句一旦匹配到第一个符合的模式,执行完对应的代码块就会直接退出整个流程,这就是为什么你的脚本里FRUIT="apple"时只会输出苹果那行,不会管后面的香蕉和猕猴桃。
要实现匹配后不终止、继续遍历后续模式,分两种场景来处理:
1. 使用Bash/Zsh等支持扩展语法的Shell
这类Shell提供了两个特殊的终止符来改变case的默认行为:
;&:执行完当前代码块后,直接进入下一个模式的代码块执行,不再检查下一个模式是否匹配;;&:执行完当前代码块后,继续检查后续的模式,如果匹配就执行对应的代码块
针对你的场景,如果你希望匹配apple后继续检查后续所有模式(比如后续模式能匹配当前值时就执行),可以用;;&;如果不管后续模式是否匹配都要执行代码块,就用;&。
修改后的脚本示例(用;;&):
#!/bin/bash FRUIT="apple" case "$FRUIT" in "apple") echo "Apple pie is quite tasty." ;;& # 继续检查后续模式 "banana") echo "I like banana nut bread." ;;& "kiwi") echo "New Zealand is famous for kiwi." ;; esac
这个脚本里,FRUIT是apple,匹配第一个模式后会继续检查后面的banana和kiwi,但这两个模式和apple不匹配,所以只会输出苹果那行。如果你的FRUIT是带通配符匹配的场景(比如FRUIT="applekiwi",模式设为*apple*),;;&就会让后续匹配的模式也执行。
如果换成;&,脚本会输出三行内容——执行完苹果的代码块后,直接执行香蕉和猕猴桃的代码块,完全跳过模式检查。
2. 兼容POSIX标准的/bin/sh
如果你的脚本必须在严格POSIX兼容的Shell环境下运行(比如部分系统的默认sh不支持;&/;;&),可以用多个if语句模拟遍历所有模式的效果:
#!/bin/sh FRUIT="apple" # 把检查逻辑封装成函数,代码更清晰 check_all_fruits() { local fruit="$1" if [ "$fruit" = "apple" ]; then echo "Apple pie is quite tasty." fi if [ "$fruit" = "banana" ]; then echo "I like banana nut bread." fi if [ "$fruit" = "kiwi" ]; then echo "New Zealand is famous for kiwi." fi } check_all_fruits "$FRUIT"
这样每个条件都会被依次检查,满足的就执行,完美模拟了“遍历所有模式”的需求。
内容的提问来源于stack exchange,提问作者Jideofor5050
相关产品推荐
相关产品推荐

