문자열 패턴 매칭 =~

문자열 패턴 매칭 =~

문자열 패턴 일치를 이해하는 데 문제가 있습니다.=~존재하다세게 때리다.

나는 다음 함수를 작성했습니다(당황하지 마세요. 이것은 단지 실험일 뿐이며 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 -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

=~( ) 안은 [[ ]]정규식 패턴 일치(또는 오히려,찾다, 아래 참조). 이는 파일 이름 와일드카드와 동일한 패턴을 사용하는 =(or)와 다릅니다 .==

특히 정규 표현식의 별표는 "이전 단위의 복사본 0개 또는 1개"를 의미하므로 더하기 0개 이상의 s를 abc*의미합니다 .abc

귀하의 경우, 후행 별표는 함수 매개변수의 마지막 문자를 선택 사항으로 만듭니다. 마지막 예에서는 패턴이 가 되며 ...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; 
}

관련 정보