【问题标题】:Nested case statement within if then statementif then 语句中的嵌套 case 语句
【发布时间】:2018-07-15 17:29:34
【问题描述】:

我在运行一个简单的脚本时遇到了问题,如果没有新的 case 语句,它就可以正常工作。我希望我的脚本能够“捕获”用户“意外”输入的特殊字符作为命令行上的参数并输出错误消息。我目前的情况如下:

if [ $# -eq 0 ]
then echo "Please enter a filename."
else
  if [ -f $1 ]
  then
    starting_data=$1
    sed '/^id/ d' $starting_data > raw1
    sed 's/-//' raw1 > raw2
    sed 's/-//' raw2 > raw3
    sed 's/,//' raw3 > raw4
    sed 's/,/:/' raw4 > raw5
    cut -f1 -d\  raw5 > col3
    cut -f2 -d\  raw5 > col2
    cut -f3 -d\  raw5 > col1
    paste -d\  col1 col2 col3 > final
    name="Joe"
    echo $name
    date
    cat final
  else
     if case $1 in
          [!@#$%^&*()-_=+{}\|;:'",<>?/]) echo "One or more characters not 
supported."
                                         echo "Please try again."
                                         ;;
        esac
     else
    echo "$1 cannot be found."
     fi
  fi
fi

【问题讨论】:

  • 欢迎来到 SO,如果您可以让我们知道示例输入和示例输出,则无需使用这么多 sedawks,我们也可以尝试帮助您。跨度>
  • 您遇到了什么样的“麻烦”?请详细说明。
  • 这是我运行脚本 hw9.sh 并提供简单参数(不存在的文件)的示例 $ ./hw9.sh xxx ./hw9.sh: 第 23 行:语法意外令牌&amp;' ./hw9.sh: line 23: 附近出错@ [!@#$%^&*()-_=+{}\|;:'",?/]) echo "一个或多个字符不支持。"'跨度>
  • 添加一个shebang,然后将您的脚本粘贴到那里:shellcheck.net
  • sed -e '/^id/ d' -e 's/-//' -e 's/-//' -e 's/,//' -e 's/,/:/' "$starting_data" | cut -f1-3 -d\ &gt; final 和进一步优化以摆脱cut 也是可能的。

标签: bash unix if-statement case


【解决方案1】:

直接的问题是字符类表达式[!@#$%^&amp;*()-_=+{}\|;:'",&lt;&gt;?/]包含了一些需要转义的字符(至少在bash中,其他shell可能不同),而-被视为表示一个字符范围除非它位于表达式的开头或结尾。这似乎对我有用:[-!@#$%^\&amp;*\(\)_=+{}\|\;:\'\",\&lt;\&gt;?/\\],但我不推荐它。相反,我建议使用允许字符的否定表达式,例如 [^[:alnum:].][^a-zA-Z0-9.](即任何字符除了字母、数字或句点)。

第二个问题:模式只匹配一个不受支持的字符,而不是一个字符串包含一个不受支持的字符。所以你实际上想要*[^[:alnum:].]*

第三个问题:您试图在 if 语句(即 if case...)中直接使用 case,这在技术上是合法的,但可能并不意味着您想要的。只需将if 部分去掉,并使用* 模式作为else 案例:

case $1 in
  *[^[:alnum:].]* )
    echo "One or more characters not supported."
    echo "Please try again."
    ;;
  * )
    echo "$1 cannot be found."
    ;;
 esac

其他一些潜在问题:如果变量中有任何有趣的字符,您有许多未加引号的变量引用(例如if [ -f $1 ])可能会引起麻烦;这些应该几乎总是双引号(例如if [ -f "$1" ])。您还在 查找文件后检查不受支持的字符;如果文件存在名称中包含不受支持的字符,脚本应该继续运行,还是拒绝它并抱怨?请注意,在 unix 文件名中几乎所有内容都是合法的。

最后,正如 RavinderSingh13 在评论中所说,没有必要使用这么长的sed 命令字符串。如果不知道更多关于文件格式和你想用它做什么,很难提出好的建议,但我相信有更好的方法。

【讨论】:

    最近更新 更多