POSIX 在 case 语句中捕获换行符

aaa*_*aaa 9 posix newlines case

我想在 POSIX shell(破折号)的 case 语句中捕获变量是否为多行。

我试过这个:

q='
'
case "$q" in
    *$'\n'*) echo nl;;
    *) echo NO nl;;
esac
Run Code Online (Sandbox Code Playgroud)

nl以 zsh 形式返回,但NO nl以破折号形式返回。

谢谢。

Kus*_*nda 13

dash外壳没有C字符串($'...')。C-strings 是 POSIX 标准的扩展。您将不得不使用文字换行符。如果将换行符存储在变量中,这会更容易(并且看起来更好):

#!/bin/dash

nl='
'

for string; do

    case $string in
        *"$nl"*)
            printf '"%s" contains newline\n' "$string"
            ;;
        *)
            printf '"%s" does not contain newline\n' "$string"
    esac

done
Run Code Online (Sandbox Code Playgroud)

对于给脚本的每个命令行参数,这会检测它是否包含换行符。case语句( $string) 中使用的变量不需要引用,也不需要;;最后一个case标签之后的。

测试(来自交互式zshshell,这是dquote>辅助提示的来源):

$ dash script.sh "hello world" "hello
dquote> world"
"hello world" does not contain newline
"hello
world" contains newline
Run Code Online (Sandbox Code Playgroud)

  • `$nl` 不需要在 `case` 语句中引用,但如果它包含通配符,则需要引用。虽然 `;;` 在 `esac` 之前是可选的,省略它会使维护变得更加困难,因为如果你添加另一个案例,你必须记住添加它,所以我建议总是包含它。 (4认同)
  • @Gilles'SO-stopbeingevil' 是的,应该引用 `$nl`(现在已修复),但是在 `esac` 之前使用或不使用 `;;` 显然是一个品味问题。 (3认同)