Bash

使用 =~ 進行字元串模式匹配

  • March 26, 2018

我在理解 bash 中與 =~ 匹配的字元串模式時遇到****問題

我編寫了以下函式(不要驚慌——它只是在試驗,而不是 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

是我,沒有意識到這應該如何工作(選擇被破壞),還是在 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 僅對無意錯誤有用,對攻擊無效。我不鼓勵使用它。

這個問題不是尋找更好的解決方案或變通方法。它是關於**=~**運算符的,它是否應該這樣做,如果是,為什麼。

=~in ( [[ ]]) 是一個正則表達式模式匹配(或者更確切地說,一個search,見下文)。這與=(or ==) 不同,後者使用與文件名萬用字元相同的模式。

特別是,正則表達式中的星號表示“前一個單元的零個或一個副本”,因此abc*表示ab加上零個或多個cs。

在您的情況下,尾隨星號使函式參數的最後一個字元是可選的。在您的最後一個範例中,模式變為...68d3G*,並且由於G*匹配空字元串,因此它匹配類似...68d3. “任何字元串”的正則表達式是.*,或“任何字元,任意次數”。

請注意,正則表達式匹配在字元串中的任何位置搜尋匹配,它不需要是整個字元串。所以模式cde會在字元串中找到abcdefgh

你可能想使用這樣的東西:

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

我們在這裡並不真正需要正則表達式匹配,因為md5sum無論如何都會輸出尾隨空格(加上文件名),我們可以在模式中使用它來檢查我們是否與完整模式匹配。所以給函式一個截斷的雜湊是不匹配的。

引用自:https://unix.stackexchange.com/questions/415839