为什么我的变量在测试语句中起作用,但在我使用 echo 将其读入自身之前却在 case 语句中不起作用?

Why does my variable work in a test statement, but not in a case statement until I use echo to read it into itself?

我有一行评论。我使用参数替换将行条件化为变量 "source"。一条测试语句显示source的值为"Simple:",但case语句匹配不到。如果我对 "source=$(echo $source)" 使用命令替换,测试表明它匹配,就像以前一样,并且 case 语句现在可以工作。我是否遗漏了一些基本的东西,我不应该使用参数替换来做到这一点,还是这很奇怪? Bash 版本:GNU bash,版本 4.4.20(1)-release (x86_64-pc-linux-gnu)。谢谢参观。

使用 echo 将行通过管道传递给 sed 可以正常工作。如果没有对变量执行参数替换,则 case 会按预期工作。示例:line="Simple:" 和 case $line in ... 没有问题。

#!/bin/bash

line="Simple: #comment and space to be removed"
source=${line//#*}
source=${source//^[[:space:]]*}
source=${source//*[[:space:]]$}

[[ $source =~ 'Simple:' ]] && echo -e "\n1st test match" || echo -e "\nno 1st test match"

case $source in
    'Simple:')  
        ops="Simple"
        echo -e "\n1st try case match.  Ops is $ops"
    ;;
    *)
        echo -e "\nno natch in 1st case"
    ;;
esac

source=$(echo $source)

[[ $source =~ 'Simple:' ]] && echo -e "\n2nd test match" || echo -e "\nno 2nd test match"

case $source in
    'Simple:')  
        ops="Simple"
        echo -e "\n2nd try case match.  Ops is $ops"
    ;;
    *)
        echo -e "\nno match 2nd case"
    ;;
esac

我希望 "Simple:" 会在第一个 case 语句中匹配,但直到我 运行 "source=$(echo $source)".

引用自man bash

${parameter/pattern/string}

Pattern substitution. The pattern is expanded to produce a pattern just as in pathname expansion, Parameter is expanded and the longest match of pattern against its value is replaced with string. ...

也就是说,这些行:

source=${source//^[[:space:]]*}
source=${source//*[[:space:]]$}

什么都不做,^$ 在路径名扩展中不起作用; patternnot a regex. source=$(echo $source) makes it work because since $source is not in double-quotes, its value undergoes word splitting,最后的 space 丢失了。

使用 parameter expansions 执行此操作的正确方法是:

source=${line%%#*}
source=${source#${source%%[^[:space:]]*}}
source=${source%${source##*[^[:space:]]}}