【问题标题】:How to write and match regular expressions in /bin/sh script?如何在 /bin/sh 脚本中编写和匹配正则表达式?
【发布时间】:2015-08-19 06:57:23
【问题描述】:

我正在为没有 bash 的基于 unix 的有限微内核编写一个 shell 脚本! /bin/sh 由于某些原因无法运行以下行。

if [[ `uname` =~ (QNX|qnx) ]]; then
read -p "what is the dev prefix to use? " dev_prefix
if [[ $dev_prefix =~ ^[a-z0-9_-]+@[a-z0-9_-"."]+:.*$ ]]; then

对于第 1 行和第 3 行,它抱怨缺少表达式运算符,而对于第 2 行,它说没有协同处理!谁能阐明 /bin/bash 和 /bin/sh 脚本之间的区别?

【问题讨论】:

标签: regex shell unix sh


【解决方案1】:

您可以使用shellcheck 来检测脚本中的非 Posix 功能:

复制/粘贴到https://www.shellcheck.net/

#!/bin/sh
if [[ `1uname` =~ (QNX|qnx) ]]; then
  read -p "what is the dev prefix to use? " dev_prefix
  if [[ $dev_prefix =~ ^[a-z0-9_-]+@[a-z0-9_-"."]+:.*$ ]]; then
    : nothing
  fi
fi

或者在本地安装shellcheck,然后运行shellcheck ./check.sh, 它将突出显示非 posix 功能:

In ./check.sh line 2:
if [[ `1uname` =~ (QNX|qnx) ]]; then
   ^-- SC2039: In POSIX sh, [[ ]] is not supported.
      ^-- SC2006: Use $(..) instead of deprecated `..`

In ./check.sh line 4:
  if [[ $dev_prefix =~ ^[a-z0-9_-]+@[a-z0-9_-"."]+:.*$ ]]; then
     ^-- SC2039: In POSIX sh, [[ ]] is not supported.

您要么必须将表达式重写为 glob(不现实),要么使用外部命令 (grep/awk),@anubhava 对此进行了解释

【讨论】:

    【解决方案2】:

    您可以在/bin/sh 中使用此等效脚本:

    if uname | grep -Eq '(QNX|qnx)'; then
       printf "what is the dev prefix to use? "
       read dev_prefix
       if echo "$dev_prefix" | grep -Eq '^[a-z0-9_-]+@[a-z0-9_-"."]+:'; then
       ...
       fi
    fi
    

    【讨论】:

    • 我会选择 printf 而不是 echo -n,这是非标准的。
    • 应该是if [ -n "$1" ] in /bin/sh
    • 良好的 bash 到 sh 转换,它回答了核心问题(赞成)。我想知道这个“有限的基于 unix 的微内核”是否也有旧的 grep,需要旧的 RE 形式。 printf 命令也可能不存在。任何人都记得使用 \c ... 的 echo 版本吗? (我显然不知道 QNX。)
    • 效果很好。我才意识到-也应该被双引号如下:'^[a-z0-9_"-"]+@[a-z0-9_"-."]+:'
    • @moorara - 可以包含在一个字符类中,无需额外引用,例如:'^[-a-z0-9_-]+@[-a-z0-9_.]+:'
    猜你喜欢
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    • 2021-09-21
    相关资源
    最近更新 更多