이것은 zsh 확장 글로브 패턴입니다. 요점은 특정 하위 계층을 제외하고 디렉터리 계층 아래의 모든 파일을 패턴과 일치시키는 것입니다. 제목의 패턴은 작동하지만 반복할 필요가 없는 것을 원합니다 long/path/
.
나는 다음을 시도했다:
long/path/(^(bad-1|bad-2)/|)**/^*.(complex|pattern)(.)
long/path/(**~(bad-1|bad-2)/*)/^*.(complex|pattern)(.)
다음에 추가 KSH_GLOB
:
long/path/?(^(bad-1|bad-2)/)**/^*.(complex|pattern)(.)
모두 잘못된 모드 오류로 이어집니다. 문제는 /
괄호 안에 있는 것 같습니다. 문서에는 다음과 같이 나와 있습니다.
위에서 언급한 것처럼 디렉터리 구분 기호로 사용되는 "/"는 괄호 안에 표시되지 않을 수 있습니다.
(dir/)#
이것은 매우 좋은 패턴이기 때문에 나를 혼란스럽게 합니다 . 문서에는 다음과 같은 내용도 언급되어 있습니다.
"(foo/)#" 형식의 경로 이름 구성 요소는 foo 패턴과 일치하는 0개 이상의 디렉터리로 구성된 경로와 일치합니다.
이건 예외인 것 같아요.
분명히 말하면 나는 동등한 것을 찾고 있습니다. 여기에는 다음이 포함되지 않습니다.
long/path/^(bad-1|bad-2)/**/^*.(complex|pattern)(.)
long/path/good.pattern
, 등을 제외하기 때문입니다.
long/path/(^(bad-1|bad-2)/)#/^*.(complex|pattern)(.)
long/path/**/^*.(complex|pattern)~*/(bad-1|bad-2)/*(.)
왜냐하면 이것들은 다음과 같은 것들을 제외하기 때문입니다 long/path/good/bad-1
.
편집: 그런데 솔루션에서 반드시 와일드카드만 사용할 필요는 없습니다. 중괄호나 기록 확장 또는 다른 zsh 도구를 추가하여 수행할 수 있다면 좋을 것입니다.
편집 2: 내 생각에 따라 기록 확장을 시도했습니다.
long/path/**/^*.(complex|pattern)~!{#$:s/\**//}/(bad-1|bad-2)/*(.)
그러나 이는 1) 현재 줄의 마지막 단어가 확장이 있는 줄 앞의 단어이고, 2) 전역 확장 후에 히스토리 교체가 수행되는 것처럼 보이기 때문에 실패합니다. 아마도 모든 확장은 그대로 수행될 것입니다.
나는 또한 중괄호 확장을 시도했습니다.
( IFS=\~; printf "%s\n" long/path/{**/^*.(complex|pattern),(bad-1|bad-2)/*(.)} )
작동하지 않습니다. 2개의 glob 패턴은 여전히 단일 패턴으로 연결되지 않고 별도의 단어로 처리됩니다. IFS
여기서는 그것이 고려되지 않은 것 같습니다 . 말이 되네요.
또한 전역 한정자에서 대체를 시도했습니다.
+/**/^*.(complex|pattern)~+/(bad-1|bad-2)/*(.:s,+,long/path,)
하지만 물론 교체는 경기 전이 아닌 경기 후에 이루어지므로 이는 효과가 없습니다.
답변1
알았어! 이중 슬래시 태그 접두사:
long/path//**/^*.(complex|pattern)~*//(bad-1|bad-2)/*(.)
때로는 목적을 발견할 때까지 기능이 무엇인지 깨닫지 못하는 경우도 있습니다. 연속 슬래시가 1과 동일하다는 사실이 실제로 그렇게 유용할 수 있다는 사실을 믿을 수 없습니다. :)
답변2
(...)
/
예외로 사용되는 문서 목록 :
그룹화는 여러 디렉터리로 확장될 수 없습니다. 그룹 내에 "/"가 있으면 오류가 발생합니다(이는 파일 이름 생성에 사용되는 패턴에만 적용됩니다). 한 가지 예외가 있습니다. 전체 경로 세그먼트로 나타나는 (pat/)# 형식 집합은 디렉터리 범위와 일치할 수 있습니다.
그렇지 않으면 표현식을 사용하여 결과를 필터링하여 중복을 피할 수 있습니다.
% print -l a/**/*(.)
a/b/c/foo/file
a/b/d/foo/file
a/bad/e/foo/file
a/nope/d/foo/file
% print -l a/**/*(.e:'[[ $REPLY != *(bad|nope)* ]]':)
a/b/c/foo/file
a/b/d/foo/file