이 정규 표현식과 함께 sed 사용:
message=$(echo "$path" | sed -E 's/(.+pattern[0-9][0-9]*).+/\1/')
이 표현식을 사용하면 다음과 같은 줄이 표시됩니다.
/lol/pattern03657/qsd/qsd/pattern0001/qsd/
다음으로 대체됩니다:
/lol/pattern03657/qsd/qsd/pattern0001
반면에 나는 그들이 다음과 같기를 바랍니다:
/lol/pattern03657/
나는 sed가 첫 번째 발생만 대체할 것이라고 생각했지만 그렇지 않은 것 같습니다. 내 코드가 이런 식으로 동작하게 하려면 무엇을 변경해야 합니까?
답변1
그 이유는 *
, +
은 탐욕적 수량자로서 가능한 한 많이 일치시키려고 노력할 것이기 때문입니다.
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | sed -E 's/(.+pattern[0-9][0-9]*).+/\1/'
/lol/pattern03657/qsd/qsd/pattern0001
perl
?
에 추가하여 탐욕스럽지 않은 수량자를 갖습니다.+
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | perl -pe 's/(.+?pattern\d+\/).+/\1/'
/lol/pattern03657/
또는 가능한 경우 옵션 grep
과 함께 사용pcre
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | grep -oP '^.+?pattern\d+/'
/lol/pattern03657/
한 가지 해결 방법 sed
은 문자열이 어디에 있는지 아는 것입니다. 예를 들어:
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | sed -E 's|^(/[^/]+/pattern[0-9][0-9]*/).+|\1|'
/lol/pattern03657/
여기서 줄의 시작 부분부터 한 세트가 /text/
문자열 앞에 옵니다.