zsh 매개변수 확장에는 어떤 모드를 사용할 수 있나요?

zsh 매개변수 확장에는 어떤 모드를 사용할 수 있나요?

내 zsh 쉘 스크립트에서 regexp-replace nname "_{2,}" "_"여러 개의 "_"를 하나로 성공적으로 줄였지만 zsh를 시도하면 ${nname//_{2,}/'_'}패턴과 일치하지 않는 것 같습니다.

man zshexpn예. 확실하지 않다. 여기에는 와일드카드 패턴이 언급되어 있지만 ${name//[^[:alnum:]]/"_"} 내 스크립트에서 제대로 작동하는 것과 같은 다른 POSIX 1003.2 정규식이 있는 것 같습니다 .

동기 부여

다음과 동일한 매개변수 확장을 찾고 있습니다.

regexp-replace nname "[^[:alnum:]]" "_"
regexp-replace nname "_{2,}" "_"
regexp-replace nname "_+$" ""
regexp-replace nname "^_+" ""

다루기 힘든

zsh --version
zsh 5.7.1 (x86_64-apple-darwin19.0)

답변1

${var//pattern/replacement}zsh 와일드카드 패턴 사용 pattern(사용된 것과 동일)파일 이름 생성와일드카드라고도 알려져 있으며 sh와일드카드 패턴의 상위 집합입니다. 구문은 kshglobextendedglob옵션의 영향도 받습니다. 원래 ${var//pattern/replacement}Korn 쉘에서 유래되었습니다.

귀하의 경우 extendedglob이를 활성화하는 것이 좋습니다 . 이는 표준 ERE보다 더 많은 기능을 제공하지만 일부 특수한 경우에는 이전 버전과의 비호환성을 유발할 수 있습니다.set -o extendedglob~/.zshrc

로그인되어 있는 것을 볼 수 있습니다 info zsh 'filename generation'.

ERE와 확장 zsh 와일드카드 간의 매핑을 위한 치트 시트:

기준 sh:

  • .->?
  • .*->*
  • [...]->[...]

zsh 확장자:

  • *->#
  • +->##
  • {x,y}->(#cx,y)
  • (...|...)->(...|...)

일부 추가 기능은 표준 ERE에서 사용할 수 없습니다.

  • ^pattern(부정적인)
  • x~y(와는 별개로)
  • <12-234>소수 범위 일치
  • (#i)대소문자를 구분하지 않는 일치
  • (#a2)대략적인 일치에서는 최대 2개의 오류가 허용됩니다.
  • 더 많은 것이 있습니다

와일드카드 패턴이 주제의 시작 부분에 고정되는지 아니면 끝 부분에 고정되는지 여부는 사용되는 연산자에 따라 다릅니다.

  • Glob, case패턴 [[ string = pattern ]]${var:#pattern}모두 고정되어 있습니다( 대신 f*.txt일치함 ).foo.txtXfoo.txtY
  • ${var#pattern}그리고 ${var##pattern}처음에 고정됨
  • ${var%pattern)그리고 ${var%%pattern}마지막에 고정됨
  • ${var/pattern/repl}고정되어 있지는 않지만 ${var//pattern/repl}(시작) 또는 (끝)을 통해 달성할 수 있습니다.${var/#pattern}${var/%pattern}

(#s)/ (ERE) 또는 / (PCRE) 와 동등하게 (#e)사용될 수도 있습니다 .^$\A\z

반복 연산자( #, ##, *, (#cx,y), <x-y>)가 탐욕적인지 여부는 연산자에 따라 다르며( , 에 탐욕 ##, %%, 탐욕 //아님 ) 매개변수 확장 플래그를 통해 변경할 수 있습니다 ./#%S

귀하의 예를 들면 다음과 같습니다.

  • regexp-replace nname "[^[:alnum:]]" "_":${var//[^[:alnum:]]/_}
  • regexp-replace nname "_{2,}" "_":${var//_(#c2,)/_}
  • regexp-replace nname "_+$" "": ${var%%_#}또는 ${var/%_#}(여기서는 #동등한 항목을 *사용할 수 있지만 이 경우에는 아무런 차이가 없습니다).##+
  • regexp-replace nname "^_+" "": ${var##_#}또는${var/#_#}

여기에서 이들을 결합할 수 있습니다 ${${${var//[^[:alnum:]]##/_}#_}%_}(alnum이 아닌 시퀀스를 변환 _하고 최종 선행 또는 후행 시퀀스 제거 _).

_또 다른 접근 방식은 다음 해킹을 사용하여 모든 alnums 시퀀스를 추출하고 이를 와 결합하는 것입니다 .

words=()
: ${var//(#m)[[:alnum:]]##/${words[1+$#words]::=$MATCH}}
var=${(j:_:)words}

regexp-replace[[ $var =~ pattern ]]주기적으로 호출되는 자동 로딩 기능입니다. 참고로 결과는,^앵커나 단어 경계 또는 뒤보기 연산자(해당 rematchpcre옵션을 사용하는 경우) 에서는 제대로 작동 하지 않습니다.:

$ a='aaab'; regexp-replace a '^a' x; echo "$a"
xxxb
$ a='abab'; regexp-replace a '\<ab' '<$MATCH>'; echo $a
<ab><ab>

(첫 번째 예에서는 , , 이 루프에서 일치합니다 ^a.)aaabaababb

관련 정보