다음과 같은 디렉터리 구조가 있다고 가정해 보겠습니다.
% tree foo
foo
├── bar
│ └── baz
└── baz
두 가지를 우아하게 매치하는 방법foo/bar/baz
그리고 foo/baz
? 즉, bar/
경로의 구성 요소를 선택적으로 만드는 방법은 무엇입니까 ?
foo/*/baz
유효한 확장자가 아니기 foo/bar/baz
때문에 일치합니다 . foo//baz
선택적 그룹을 사용해 보았지만 다음과 같습니다.
% set -o KSH_GLOB
% echo foo/?(bar)/baz
또한 foo/bar/baz
같은 이유로 ( foo//baz
유효한 확장자가 아님) 로 확장됩니다. /
에 따르면 그룹 내에 a를 포함하는 것은 일반적으로 불법이므로 zshexpn(1)
예를 들어 foo/?(bar/)baz
오류가 발생합니다.
특별히 이상한 경우는 아닌 것 같은데, 구글 검색이나 SE 검색에서는 관련 내용을 찾을 수 없습니다.
답변1
이것은 ksh 및 zsh glob의 문제점입니다. 중괄호를 사용할 수 있습니다.
echo foo{,/bar}/baz
echo foo{,/*}/baz # you probably don't want this one, see below
그러나 교정기는 전체가 아니며, 교정기가 충분히 가까운지 여부는 수행 중인 작업에 따라 다릅니다.
주요 질문은 어떤 파일이 존재하는지, 일부 파일이 존재하지 않는 경우 어떻게 되기를 원하는지입니다. foo{,/bar}/baz
두 단어로 확장되고 foo/baz
파일 foo/bar/baz
이 존재하는지 여부. 와일드카드를 사용하면 기본적으로 foo{,/*}/baz
일치하는 파일이 없으면 오류가 발생합니다 . 존재 foo/*/baz
하더라도 마찬가지입니다 . foo/baz
다음 방법으로 이 문제를 해결할 수 있습니다.N
와일드카드 플래그:
echo foo{/*,}/baz(N)
그러면 일치하는 기존 파일 목록 foo/*/baz
(목록이 비어 있더라도) 으로 확장되고 . 이는 작동하면 얻을 수 있는 것과 foo/baz
동일합니다 . foo/(*/|)/baz(N)
반면에 간단하게 동등한 것은 없습니다 foo/(*/|)/baz
. 일치하는 항목이 없을 때 오류가 발생하려면 직접 수행해야 합니다.
bazes=(foo{,/*}/baz(N))
if (($#bazes == 0)); then echo >&2 "No bazes are belong to us"; return 1; fi
중괄호와 glob의 또 다른 차이점은 중괄호 내의 순서에 따라 확장 순서가 결정된다는 것입니다. 예를 들어 수정 시간에 관계없이 echo foo{,/*}/baz(Nom)
항상 먼저 입력하세요 .foo/baz
답변2
실수로 >1개의 "선택적" 경로 이름 구성 요소를 일치시킨 경우에는 문제가 되지 않습니다. 다음을 수행할 수 있습니다.
% set -o EXTENDED_GLOB
% echo foo/(bar/)#baz
foo/bar
이는 및 와 일치 foo/bar/baz
하지만 foo/bar/bar/baz
등과 도 일치합니다.
답변3
두 위치에서 일치하는 파일을 원하는지 명시적으로 말하지 않았습니다.오직, 또는모두그들은 나무에 있습니다. 모든 항목을 일치시킬 수 있는 옵션이 있는 경우 다음을 사용할 수 있습니다 **
.
% mkdir -p foo/{bar,asdf/asdf,}/baz
% echo foo/**/baz
foo/asdf/asdf/baz foo/bar/baz foo/baz
Bash에서도 작동합니다( globstar
활성화됨).
$ shopt -s globstar
$ echo foo/**/baz
foo/asdf/asdf/baz foo/bar/baz foo/baz
(zsh와 Bash 사이에는 몇 가지 주의 사항/차이점이 있습니다 **
. 트리의 기호 링크입니다.)