字符串模式匹配 =~

字符串模式匹配 =~

我在理解字符串模式匹配时遇到问题=~巴什

我编写了以下函数(不要惊慌 - 这只是实验,而不是 md5sum 的安全方法):

md5 ()  { 
     [[ "$(md5sum $1)" =~ $2* ]] && echo fine || echo baarr; 
}

并用一些输入对其进行了测试。这里有一些参考:

md5sum wp.laenderliste
b1eb0d822e8d841249e3d68eeb3068d3  wp.laenderliste

如果控制总和的源不包含文件名的两个空格,则比较会不必要地困难。这就是观察的来源,但比解决该问题的许多方法更有趣的是我的观察:

我定义了一个控制变量,并使用太短但匹配的字符串测试我的函数:

ok=b1eb0d822e8d841249e3d68eeb3068d3
for i in {29..32}; do md5 wp.laenderliste ${ok:1:$i} ;done 
fine
fine
fine
fine

这是预期的并且很好,因为它是该函数的目的,忽略丢失的“wp.laenderliste”的不匹配,从而忽略更长的不匹配。

现在,如果我附加不匹配的随机内容,我当然希望出现错误,并得到它们:

for i in {29..32}; do md5 wp.laenderliste ${ok:1:$i}GU ;done 
baarr
baarr
baarr
baarr

正如预期的那样。但当有只有最后一个不匹配字符, 走着瞧吧:

for i in {29..32}; do md5 wp.laenderliste ${ok:1:$i}G ;done 
fine
fine
fine
fine

这是我,没有意识到这是如何工作的(select 被破坏),还是 bash 的模式匹配中真的存在逐一错误?

字符串中间的不匹配与计数 1 相关:

for i in 5 9 e ; do echo md5 wp.laenderliste ${ok//$i/_} ;done 
md5 wp.laenderliste b1eb0d822e8d841249e3d68eeb3068d3
md5 wp.laenderliste b1eb0d822e8d84124_e3d68eeb3068d3
md5 wp.laenderliste b1_b0d822_8d841249_3d68__b3068d3

for i in 5 9 e ; do md5 wp.laenderliste ${ok//$i/_} ;done 
fine
baarr
baarr

bash 版本:

bash -version
GNU bash, Version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
Lizenz GPLv3+: GNU GPL Version 3 oder jünger <http://gnu.org/licenses/gpl.html>

免责声明: md5sum 仅对防止无意错误有用,不能防止攻击。我不鼓励使用它。

这个问题并不是寻找更好的解决方案或解决方法。这是关于=~操作员,是否应该按其应有的方式行事,如果是,为什么。

答案1

=~( ) 中[[ ]]是正则表达式模式匹配(或者更确切地说,搜索, 见下文)。这与=(或)不同,==它使用与文件名通配符相同的模式。

特别地,正则表达式中的星号表示“前一个单元的零个或一个副本”,因此abc*表示ab加上零个或多个cs。

在您的情况下,尾随星号使函数参数的最后一个字符成为可选。在最后一个示例中,模式变为...68d3G*,并且由于G*匹配空字符串,因此它匹配类似 的字符串...68d3。 “任何字符串”的正则表达式是.*或“任何字符,任意次数”。

请注意,正则表达式匹配会在字符串中的任何位置搜索匹配项,它不需要是所有的细绳。所以cde可以在字符串中找到模式abcdefgh

你可能想使用这样的东西:

[[ "$(md5sum -- "$1")" = "$2 "* ]] && echo ok

或者

[ "$(md5sum < "$1")" = "$2  -" ] && echo ok

我们在这里实际上并不需要正则表达式匹配,并且由于md5sum无论如何都会输出尾随空格(加上文件名),因此我们可以在模式中使用它来检查我们是否与完整模式匹配。因此,为函数提供截断的哈希值将不匹配。

答案2

我不会在这里使用正则表达式,只是字符串比较:

md5 ()  { 
    sum=$(md5sum "$1" | awk '{print $1}')
    [[ $sum = "$2" ]] && echo fine || echo baarr; 
}

相关内容