반면:
$ shopt -s extglob
$ TEST=" z abcdefg";echo ">>${TEST#*( )z*( )}<<"
>> abcdefg<<
문자 "a" 앞에 공백이 있는 이유는 무엇입니까? 두 번째도 *( )
공간에 어울리게 하고 싶었는데 그렇게 하기엔 적합하지 않네요.
나는 다음과 같은 결과를 기대합니다:
$ echo ">>$(echo -n "${TEST}" | perl -pe "s/^ *z *//g")<<"
>>abcdefg<<
*( )
다음 문자(예: "a")를 지정하면 두 번째 문자가 일치합니다.
$ shopt -s extglob
$ TEST=" z abcdefg";echo ">>${TEST#*( )z*( )a}<<"
>>bcdefg<<
히트 버전: GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
답변1
${TEST#...}
가장 짧은 문자열, z 뒤에 공백이 없는 문자열과 일치합니다. 당신은 ${TEST##...}
가장 긴 일치를 원합니다 .
답변2
이는 탐욕스럽지 않은 하위 문자열 제거와 사용 중인 패턴 유형 간의 상호 작용으로 인해 발생합니다.
~에서배쉬 매뉴얼,
?(pattern-list)
주어진 패턴이 0개 또는 1개 일치합니다.
*(pattern-list)
주어진 패턴의 0개 이상의 발생과 일치합니다.
+(pattern-list)
주어진 패턴과 하나 이상 일치합니다.
내가 가장 좋아하는 bash 설명에서문자열 연산,
${string#substring}
$substring
이전에 가장 짧은 일치 항목을 제거합니다$string
.
${string##substring}
$substring
가장 긴 이전 일치 항목을 제거합니다$string
.
따라서 을 지정할 때 다음과 같이 ${TEST#*( )z*( )}
말하는 것입니다. "0개 이상의 공백이 있는 가장 짧은 하위 문자열 a를 제거하고 z
그 뒤에 0개 이상의 공백이 옵니다.
마지막 공백이 있는 일치 항목은 없는 항목보다 길기 때문에 마지막 공백은 일치하지 않습니다.
이 문제를 해결하려면 ${TEST##*( )z*( )}
0개 이상의 공백으로 끝나는 가장 긴 접두사 일치를 사용하거나 ${TEST#*( )z+( )}
하나 이상의 공백으로 끝나는 가장 짧은 접두사 일치를 사용할 수 있습니다(이는 공백 1개로 끝나는 가장 짧은 접두사 일치와 기능적으로 동일함).
답변3
is (perl) 정규 표현식을 모방하려면 regex
not a 를 사용하십시오 pattern
.
$ test=" z abcdefg"
$ regex='^ *z *(.*)'
$ [[ $test =~ $regex ]]
$ echo ">>${BASH_REMATCH[1]}<<"
>>abcdefg<<
정규식은 전체 PCRE가 아닌 확장 정규식입니다.