Zsh는 문자열을 파일 이름 패턴으로 처리하고 이에 대해 불평합니다(NOMATCH 옵션).

Zsh는 문자열을 파일 이름 패턴으로 처리하고 이에 대해 불평합니다(NOMATCH 옵션).

Bash에서 나온 Zsh를 시험해보고 있습니다. Zsh가 grep 정규식에 대해 불평하는 이유를 이해하는 데 약간의 어려움이 있었습니다.

usr@rk1 ~ % tty | grep ^/dev/tty[1-7]$ > /dev/null 2>&1
zsh: no matches found: ^/dev/tty[1-7]$

(1) 정규 표현식을 따옴표로 묶거나, (2) 정규 표현식에서 슬래시를 제거하거나, (3) setopt NO_NOMATCH.

zshoptions 매뉴얼에서:

일치하지 않음 (+3) <C> <Z>

파일 이름 생성 패턴에 일치하는 패턴이 없으면 인수 목록에 변경하지 않고 그대로 두는 대신 오류를 인쇄합니다. 이는 첫 글자 '~' 또는 '='의 파일 확장에도 적용됩니다.

따라서 슬래시 때문에 정규식은 파일 이름 패턴으로 처리되는 것 같습니다. 이것이 정상적인 것으로 간주됩니까, 아니면 버그입니까?

또한 GreyCat의 Bashism 및 BashPitfalls 페이지와 유사하지만 Zsh용 페이지가 있으면 좋을 것입니다. 그런 자료를 아시나요?

답변1

옵션 을 설정한 경우 파일 이름 생성에 EXTENDED_GLOB패턴이 ^something사용됩니다. 로부터zshexpn매뉴얼 페이지:

^x (EXTENDED_GLOB를 설정해야 합니다.) x 패턴을 제외한 모든 항목과 일치합니다. 이는 보다 우선순위가 높으므로 /이름 이 지정된 파일을 제외한 ^foo/bar디렉토리를 검색합니다 .../foobar

따라서 은 (는) 현재 디렉토리의 모든 하위 디렉토리(아무 것도 제외되지 않습니다. 바로 뒤에 가 있으므로 제외되지 않음)에서 , , ... 라는 파일에 대해 1에서 7 사이 범위의 문자 1개와 정확히 일치하는 것을 찾으려고 ^/dev/tty[1-7]$합니다. is' 그런 경우에는 특별 대우를 받지 못합니다.^/dev/tty1$dev/tty2$dev/tty7$[1-7]$

당신은 이미 해결책을 찾았습니다. 캐럿을 설정하거나 NO_NOMATCH(위험할 수도 있지만 입력하는 것이 게으른 만큼 매우 마음에 듭니다 ;)) 인용부호(작은따옴표 또는 큰따옴표)를 사용하세요.

print무슨 일이 일어나고 있는지 시도해 보세요 .

$ setopt nomatch extended_glob
$ echo ^/dev/tty[1-7]$
zsh: no matches found: ^/dev/tty[1-7]$

# ^ is doing filename generation in every sub-dir
$ touch foo/dev/tty5$
$ echo ^/dev/tty[1-7]$
foo/dev/tty5$

# quote to prevent filename generation
$ echo "^/dev/tty[1-7]$"
^/dev/tty[1-7]$
$ echo '^/dev/tty[1-7]$'
^/dev/tty[1-7]$

설정 하지 않으면 EXTENDED_GLOB캐럿은 문자 그대로 일반 문자로 해석됩니다. 따라서 인용은 다시 친구입니다. 이번에는 [1-7]파일 이름 생성이 트리거됩니다.

$ setopt nomatch no_extended_glob
$ echo ^/dev/tty[1-7]$
zsh: no matches found: ^/dev/tty[1-7]$

# quote to prevent filename generation
$ echo ^/dev/tty"[1-7]"$
^/dev/tty[1-7]$

# caret is interpreted literally
$ mkdir ^/dev -p
$ touch ^/dev/tty5$
$ echo ^/dev/tty[1-7]$
^/dev/tty5$

요약하자면, 정규식 패턴을 인용하는 것은 나에게 항상 좋은 생각인 것 같습니다. 물론 저는 일반적으로 몇 가지 키 입력을 저장하려고 노력하기도 합니다.

관련 정보