long/path/**/^*.(complex|pattern)~long/path/(bad-1|bad-2)/*(.) long/path/를 반복하지 않고 더 짧은 것과 동일합니까?

long/path/**/^*.(complex|pattern)~long/path/(bad-1|bad-2)/*(.) long/path/를 반복하지 않고 더 짧은 것과 동일합니까?

이것은 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

관련 정보