2013-03-15 3 views
0

이 기능 f()은 매우 간단해야 아직이 이해할 수없는 방식으로 작동합니다호기심 배쉬 패턴 대체 동작

f() { 
    a=(cyan red green blue orange violet) 
    shopt -s extglob 
    echo 1: -${a[@]/!($1)}- 
    echo 2: -${a[@]/!($1)/}- 
    echo 3: -${a[@]/!("$1")/}- 
    echo 4: -"${a[@]/!($1)/}"- 
    echo 5: -${a[@]/!($1)/x}- 
} 
echo ORANGE 
f orange # ends in e like blue 
echo YELLOW 
f yellow 

출력은 (또한 빈/간격을 유의하시기 바랍니다)입니다 :

ORANGE 
1: - e - 
2: - e - 
3: - e - 
4: - e - 
5: -x x x x xe x- 
YELLOW 
1: - - 
2: - - 
3: - - 
4: -  - 
5: -x x x x x x- 

왜 찾은 단어의 마지막 문자 만?!

(이 경우 orangee로) 예상 출력은 orange보다는 e

주 : 나는 또한 내가 거기 빈 참조 어떤 장소에서 공백을 볼 기대 ..

+1

는'shopt 내부 -s extglob' *이 함수 내부 * 작동하지 않습니다. extglob 다음에 오는 코드는 다르게 컴파일되며 함수는 선언 될 때 컴파일됩니다 (한 번). 런타임에'shopt'를하는 것은 너무 늦었습니다. 이것은 당신의 질문에 대한 대답이 아니지만 여전히 그 문제에 대해 의문을 품고 있습니다. – cdarke

+1

@cdarke : 왜 내 코드가 작동 하나, shopt 행을 제거하면 더 이상 필요하지 않습니까? – choroba

+0

흥미로운 Bash 버전을 사용하고 있습니까? – cdarke

답변

2

문제는 패턴이 고정되어 있지 않으므로, 예를 들어 orange의 경우 orange과 일치하지 않는 가장 긴 문자열은 orang입니다. 따라서 제거되며 e 만 남아 있습니다. bash는 앵커를 지정하는 방법을 방법이 없다, 당신은 그들에게 자신을 만들 수 있습니다

아래 코멘트에 암시 @ormaaj으로
#! /bin/bash 
f() { 
    a=(cyan red green blue orange violet '1 2') 
    a=("${a[@]/#/|}") 
    a=("${a[@]/%/|}") 
    shopt -s extglob 
    echo ["${a[@]/|!($1)|/-}"] 
} 
echo ORANGE 
f orange # ends in e like blue 
echo YELLOW 
f yellow 
+2

아니요, 쉘 패턴은 항상 암시 적입니다. 양 끝이 고정되어있다. extglob도 적용되지 않습니다. 함수 내에서 절대로 설정하지 마십시오. – ormaaj

+1

@ormaaj : 어떻게 작동하나요? – choroba

+0

감동적인 통찰력에 감사드립니다. 당신이 분명히 볼 수있는 것을 볼 수 없었습니다. 허용되는 값을 변경하지 않고 패턴을 고정 할 수있는 방법이 없습니까? 단락 기호를 추가/추가하는 것입니까? – Robottinosino