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
디렉토리를 검색합니다 ..
./foo
bar
따라서 은 (는) 현재 디렉토리의 모든 하위 디렉토리(아무 것도 제외되지 않습니다. 바로 뒤에 가 있으므로 제외되지 않음)에서 , , ... 라는 파일에 대해 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$
요약하자면, 정규식 패턴을 인용하는 것은 나에게 항상 좋은 생각인 것 같습니다. 물론 저는 일반적으로 몇 가지 키 입력을 저장하려고 노력하기도 합니다.