对单词列表使用 if 语句

Lha*_* DL 8 bash pattern-matching

所以我有一个程序(比如,programA),它会给我一个输出,例如:yes, no, maybe, probably, possibly, impossible, banana

我想制作一个脚本,它可以根据该输出执行某些操作,无论它是什么。假设我只需要考虑yes,maybebanana

到目前为止,我会做的是case像这样使用:

case $program_output in
  yes) echo "good word: $program_output" ;;
  maybe) echo "good word: $program_output" ;;
  banana) echo "good word: $program_output" ;;
  *) echo "bad word: $program_output" ;;
esac
Run Code Online (Sandbox Code Playgroud)

但最近我在摆弄这个if语句,发现我可以像这样更快地做到这一点:

if [[ "yesmaybebanana" =~ ${program_output} ]]; then
  echo "good word: ${program_output}"; else echo "bad word: ${program_output}";
fi
Run Code Online (Sandbox Code Playgroud)

有什么理由我不应该为此使用该if语句吗?这是一种$program_output不能有空格的情况,并且它是可以输出的有限单词列表。

Adm*_*Bee 19

如果您想使用bash的正则表达式函数(但是它们是bash特定的,因此不可移植),您至少应该使用正确的“OR”类型运算符来强制与允许的单词之一完全匹配,如

if [[ $program_output =~ ^(yes|maybe|banana)$ ]]
then
    echo "Good word: $program_output"
else
    echo "Bad word: $program_output"
fi
Run Code Online (Sandbox Code Playgroud)

请注意,正则表达式周围不能有引号,并且单词替代项被括在^$锚之间以确保没有子字符串可以触发匹配(例如yessir否则会被模式捕获yes)。


Ark*_*zyk 18

if版本不会是一样可靠,case在这里,因为它会赶上的所有子yesmaybebanana-它将匹配bbebana等等:

#!/usr/bin/env bash

program_output='bebana'

if [[ "yesmaybebanana" =~ ${program_output} ]]; then echo "good word: ${program_output}"; else echo "bad word: ${program_output}"; fi
Run Code Online (Sandbox Code Playgroud)

输出:

good word: bebana
Run Code Online (Sandbox Code Playgroud)

而且它不是便携式的 - 尝试使用 dash 运行它:

$ dash ./a.sh
./a.sh: 6: ./a.sh: [[: not found
bad word: bebana
Run Code Online (Sandbox Code Playgroud)

您可以case通过在一行中使用多个单词来显着简化您的版本:

case $program_output in
  yes | maybe | banana) echo "good word: $program_output" ;;
  *) echo "bad word: $program_output" ;;
esac
Run Code Online (Sandbox Code Playgroud)


gle*_*man 13

bash 的扩展模式也适用于这里:

if [[ $program_output == @(yes|maybe|banana) ]]
then
    echo "program output is one of yes, maybe, banana"
fi
Run Code Online (Sandbox Code Playgroud)