我想检查文件名是否与以字母数字字符 ([a-zA-Z0-9]) 开头的特定模式匹配,并且仅包含字母数字字符加上“.”、“-”和“_”字符。
fileNamePattern="^[a-zA-Z0-9]+[\.-_]*"
if [[ $i(file from input) == $fileNamePattern ]]
then
echo "success"
else
echo "fail"
fi
这就是我尝试解决它的方法,但在“[[”之后未能告诉我意外的运算符,请帮助我。
答案1
如果将扩展正则表达式转换为通配模式,则可以使用case ... esac
in 来dash
检查变量的值是否与其匹配,而无需涉及grep
:
case $name in
[a-zA-Z0-9]*[._-]*)
echo success
;;
*)
echo failure
esac
该模式将匹配以任何匹配的字符开头[a-zA-Z0-9]
,然后还包含点、下划线或破折号的值(我认为您想要检查的内容,即使您的表达式允许最后一组字符不是存在于字符串中)。请注意,我已将破折号移至括号表达式的末尾,因为使用.
和_
( .-_
) 之间的范围没有什么意义。我还假设你不想要匹配文字反斜杠。如果这样做,请添加\\
到第二个括号表达式中。
嗯,那个看起来很好,但它不能满足您的要求,因为仍然可以匹配不是,或 的*
非字母数字字符。.
_
-
让我们尝试反转测试的含义,因此我们测试以下名称:失败:
case $name in
*[![:alnum:]_.-]*)
echo failure
;;
*)
echo success
esac
现在,我们检测到包含我们不希望出现在值中的字符的值。我们还没有正确测试该值是否开始但带有字母数字字符...
case $name in
*[![:alnum:]_.-]*)
echo 'failure (contains wrong characters)'
;;
*)
case $name in
[[:alnum:]]*)
echo success
;;
*)
echo 'failure (does not start with alnum)'
esac
esac
这最多会进行两次测试,首先检查该值是否包含我们不想要的字符,然后,如果不包含,则检查它是否以正确类型的字符开头。
答案2
POSIXly,要将字符串与正则表达式匹配,您可以使用expr
or awk
:
bre_match_anchored_at_start() { expr "x$1" : "x$2" > /dev/null; }
ere_match() { awk 'BEGIN{exit(!(ARGV[1] ~ ARGV[2]))}' "$1" "$2"; }
然后你可以使用:
if bre_match_anchored_at_start "$string" '[a-zA-Z0-9][a-zA-Z0-9._-]*$'; then
echo match
fi
或者:
if ere_match "$string" '^[a-zA-Z0-9][a-zA-Z0-9._-]*$'; then
echo match
fi
但请注意,what或a-z
match未指定,并且在 C/POSIX 语言环境之外的大多数系统上相当随机。您可以改为使用(POSIX,但并非所有实现都支持),它匹配所有字母数字字符(同样,如果不在 C 语言环境中,则可能比 52 个英文字母和 10 个十进制数字多得多)。如果您只想匹配这些,您可以这样做:A-Z
0-9
[[:alnum:]]
awk
if (export LC_ALL=C; ere_match "$string" '^[a-zA-Z0-9][a-zA-Z0-9._-]*$'); then
echo match
fi
您还可以使用标准 shell 构造来实现相同的目的,并采用否定方法:
case $string in
("" | [!a-zA-Z0-9]* | *[!a-zA-Z0-9._-]*) ;;
(*) echo match;;
esac
答案3
如果[[ "$filename" =~ pattern ]]
不可用,您可以使用grep
:
if printf '%s' "$filename" | grep -qz 'pattern'; then
echo "success"
else
echo "fail"
fi
注意,grep
使用基本正则表达式作为默认值。如果您-E
的.-P
grep