计算某个范围内的字符在字符串中出现的次数

count how many times characters from a range occur in a string

所以我对 bash 和一般的脚本编写有点陌生。我是一名学生,我们接到了一项任务,要创建一个密码检查器,检查命令的 $1 处的参数是否符合密码标准。如果 $1 为空,脚本应该生成一个可接受的密码(这部分完成非常感谢这里的另一个线程)。

我遇到问题的地方在于,由于密码的一个特定条件而检查 $1 的条件。密码标准如下:

我将脚本设置为一系列嵌套的 if 语句,这些语句会逐步消除出现的可能性——即,如果大小合适但有其他问题,则继续下一个 'level';如果尺码不对,其他都没问题,回显尺码不对等

我的脚本正确识别了大写、小写、数字、大小,并且至少有一个符号,但我不知道如何检查一个且只有一个特殊字符。

我目前的思路是运行 $1 到字符范围的grep 中,然后如果计数大于或小于1,则给出错误。我最接近的是:

echo | grep -o "[@#$%&*-=+]" | wc -l

但是输出 9 -- 我假设这是字符范围的大小。

有什么建议吗?

-在字符class中有特殊含义,它表示一个范围。将其移动到 class:

的开头或结尾
$ echo :/, | grep -o "[@#$%&*-=+]" | wc -l
3
$ echo :/, | grep -o "[@#$%&*=+-]" | wc -l
0
$ echo :/, | grep -o "[-@#$%&*=+]" | wc -l
0

对于它的价值,这里有一个解决方案,所有检查都完成了 运行 单个进程。

对于Linux:

expr \( \
        \( + "" : '.*[A-Z]' \) \& \
        \( + "" : '.*[a-z]' \) \& \
        \( + "" : '.*[0-9]' \) \& \
        \( + "" : '.*[-@#$%&*=+]' \) \& \
        \( ${#1} \>= 8 \) \& \
        \( ${#1} \<= 16 \) \
    \) != 0 \& \
    \( + "" : '.*[-@#$%&*=+].*[-@#$%&*=+]' \) = 0 >/dev/null && \
echo ok

对于 *BSD:

expr \( \
        \( "" : '.*[A-Z]' \) \& \
        \( "" : '.*[a-z]' \) \& \
        \( "" : '.*[0-9]' \) \& \
        \( "" : '.*[-@#$%&*=+]' \) \& \
        \( ${#1} \>= 8 \) \& \
        \( ${#1} \<= 16 \) \
    \) != 0 \& \
    \( "" : '.*[-@#$%&*=+].*[-@#$%&*=+]' \) = 0 >/dev/null && \
echo ok
$ myword="a!uuu??7889%"
$ res="${myword//[^,!#%&*?@^|+-]}"
$ echo "The original word : $myword"
$ echo "Special characters : $res"
$ echo "number of special characters : ${#res}"

The result is this 

The original word : a!uuu??7889%
Special characters : !??%
number of special characters : 4