bash 스크립트에서 정규 표현식으로 테스트를 어떻게 부정합니까?


173

GNU bash (버전 4.0.35 (1)-릴리스 (x86_64-suse-linux-gnu)를 사용하여 정규 표현식으로 테스트를 무효화하고 싶습니다. 예를 들어 조건부로 PATH 변수에 경로를 추가하고 싶습니다. 경로가 아직 없으면 다음과 같이하십시오.

TEMP=/mnt/silo/bin
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/Scripts:
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/local/bin
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
export PATH

나는 이것을 할 수있는 백만 가지 방법이 있다고 확신하지만, 내가 알고 싶은 것은 (잘못된)에서와 같이 조건부를 어떻게 든 부정 할 수 있는지 여부입니다.

TEMP=/mnt/silo/bin
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/Scripts:
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/local/bin
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
export PATH

답변:


193

당신은 바로, 단지 사이에 공백을 넣어 가지고 ![[같은if ! [[


14
오예 비! 펄의 은하계 특수 캐릭터 광기를 안전하게 회피 할 때, 나는 bash 공간 (배치)에서 길을 잃었다는 것을 알게된다! (파이썬처럼 장을 짜는 것이 두려움입니다.) 감사합니다!
David Rogers

126

느낌표를 괄호 안에 넣을 수도 있습니다.

if [[ ! $PATH =~ $temp ]]

그러나 오 탐지를 줄이기 위해 패턴을 고정해야합니다.

temp=/mnt/silo/bin
pattern="(^|:)${temp}(:|$)"
if [[ ! "${PATH}" =~ ${pattern} ]]

콜론으로 시작하기 전이나 끝에 콜론 (또는 둘 다)으로 일치하는 부분을 찾습니다. 쉘 변수와 이름이 충돌 할 가능성을 줄이기 위해 소문자 또는 대소 문자 변수 이름을 사용하는 것이 좋습니다.


아, 앵커링에 대해 상기시켜 주셔서 감사합니다. 지금까지 보았던 조언은 대문자를 사용하는 것이기 때문에 소문자 또는 혼합 변수 이름을 사용하는 아이디어는 bash 초보자와 혼동됩니다. 나는 당신이하고있는 요점을 이해하지만 요리 책에서 벗어나는 것을 편안하게 느낄 수있는 bash 스크립팅 예제를 충분히 보지 못했습니다.
David Rogers

4
@anyoneis는 이것에 대해 우리를 신뢰합니다. 사용자 정의 대문자 변수를 사용하지 않아야합니다. bash의 모든 변수는 확장되어 $있으므로 눈에 띄도록 대문자로 만들 필요가 없습니다.
SiegeX

내가 찾아 if [[ ! $foo =~ bar ]]보다 안전 if ! [[ $foo =~ bar ]]가 더 많은 조건을 소개 쉽게 때문에,if
CTodea

19

가장 안전한 방법은! 다음 [[ ]]과 같은 정규 표현식 부정에 대해 :

if [[ ! ${STR} =~ YOUR_REGEX ]]; then

그렇지 않으면 특정 시스템에서 실패 할 수 있습니다.


9

예 . SiegeX 가 이미 지적한 대로 테스트를 무효화 할 수 있습니다 .

그러나 정규 표현식을 사용해서는 안됩니다. 경로에 특수 문자가 포함되어 있으면 실패 할 수 있습니다. 대신 이것을 시도하십시오 :

[[ ":$PATH:" != *":$1:"* ]]

(출처)


1
이 형식을 사용해야하는 또 다른 이유는 실수로 하위 문자열과 일치하지 않기 때문입니다 (예 : "/ usr / bin"이 이미 있으므로 경로에 "/ bin"을 추가하지 못함).
Gordon Davisson

왼쪽의 콜론이 내가 원하는 고정 장치를 어떻게 제공했는지 이해하는 데 시간이 걸렸습니다. 검색 할 문자열에 재료를 추가하여 패턴을 줄이려는 생각은 기억할 가치가 있습니다. 경로의 특수 문자가 정규식 솔루션을 방해하지만 bash 패턴 솔루션이 아닌 이유를 이해하지 못합니다. 예를 들어 주시겠습니까?
David Rogers

나는 이것이 모든 경우에 안정적으로 작동한다고 생각하지 않습니다. 우수한 IMHO의 정규식 일치
Felipe Alvarez

5

그런 경우 조건부 연산자를 사용하지 않고 코드를 단순화하고 싶습니다.

TEMP=/mnt/silo/bin
[[ ${PATH} =~ ${TEMP} ]] || PATH=$PATH:$TEMP
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.