在 Bash 中使用变量作为案例模式

问题描述 投票:0回答:3

我正在尝试编写一个 Bash 脚本,该脚本在 case 语句中使用变量作为模式。但是,我就是无法让它工作。

案例说明:

case "$1" in
    $test)
        echo "matched"
        ;;
    *)
        echo "didn't match"
        ;;
esac

我试过将

$test
指定为
aaa|bbb|ccc
(aaa|bbb|ccc)
[aaa,bbb,ccc]
和其他几种组合。我还尝试将这些作为案例陈述中的模式:
@($test)
@($(echo $test))
$($test)
。也没有成功。

为清楚起见,我希望变量代表多个模式,如下所示:

case "$1" in
    aaa|bbb|ccc)
        echo "matched"
        ;;
    *)
        echo "didn't match"
        ;;
esac
bash pattern-matching switch-statement
3个回答
25
投票

您可以使用

extglob
选项:

#! /bin/bash

shopt -s extglob         # enables pattern lists like @(...|...)
test='@(aaa|bbb|ccc)'

for x in aaa bbb ccc ddd ; do
    echo -n "$x "
    case "$x" in
        $test) echo Matches.
        ;;
        *) echo Does not match.
    esac
done

3
投票

这里有点不同:

#!/bin/bash

pattern1="aaa bbb ccc"
pattern2="hello world"
test=$(echo -e "$pattern1\n$pattern2" | grep -e $1)

case "$test" in
    "$pattern1")
        echo "matched - pattern1"
        ;;
    "$pattern2")
        echo "matched - pattern2"
        ;;
    *)
        echo "didn't match"
        ;;
esac

这利用

grep
为您进行模式匹配,但仍然允许您指定要在 case-statement 结构中使用的多个模式集。

例如:

  • 如果
    aaa
    bbb
    ccc
    是脚本的第一个参数,这将输出
    matched - pattern1
    .
  • 如果
    hello
    world
    是第一个参数,这将输出
    matched - pattern2
    .
  • 否则会输出
    didn't match
    .

2
投票

使用 eval 也有效:

eval 'case "$1" in

    '$test')
        echo "matched"
        ;;
    *)
        echo "did not match"
        ;;
esac'
© www.soinside.com 2019 - 2024. All rights reserved.