** 와일드카드를 포함하는 여러 패턴이 있으므로 다음과 같이 설정합니다.
foo/**/bar.xml
foo/**/baz.xml
샘플 디렉터리 트리가 있습니다.
$ tree foo/
foo/
└── deep
├── baz.xml
└── even
└── deeper
└── baz.xml
이러한 패턴이 충족되는지 확인하는 가장 간단한 방법은 무엇입니까? 정확하게 말하자면: 0이 아닌 값을 반환합니다.없는 경우에만찾을 수 있습니다. 지금까지 제가 생각한 것은 globstar
and 를 사용하는 것입니다 nullglob
. 그러나 ls
이는 여기서는 옵션이 아니며 마치 패턴이 충족되지 않는 것처럼 현재 디렉터리를 나열합니다. 그래서 echo
다음과 같이 활용해야 합니다 .
$ (shopt -s globstar nullglob; echo foo/**/bar.xml foo/**/baz.xml) | grep .
foo/deep/baz.xml foo/deep/even/deeper/baz.xml
$ echo $?
0
그리고
$ (shopt -s globstar nullglob; echo foo/**/bar.xml foo/**/beque.xml) | grep .
$ echo $?
1
그렇습니다. 작동합니다. 하지만 어쩌면 내가 뭔가를 놓치고 있을지도 몰라더 단순하고/더 우아하다이 목표를 달성하는 방법은 무엇입니까?
답변1
다음 기능을 사용할 수 있습니다.
non_empty() (($#))
has() (
IFS=
set +o noglob
shopt -s globstar nullglob extglob
shopt -u failglob # which has precedence over nullglob!
for glob do
non_empty $glob && return
done
false
)
if has 'foo/**/bar.xml' 'foo/**/baz.xml'; then
echo matches found
fi
(또는 has 'foo/**/ba[rz].xml'
또는 (와 함께 extglob
) has 'foo/**/@(bar|baz).xml'
또는 has 'foo/**/bar.xml' || has 'foo/**/baz.xml'
)
첫 번째 일치하는 글로브에서 중지됩니다.
보다 효율적으로 만들고 첫 번째 일치에서 중지하려면 zsh
반대와 해당 Y1
glob 한정자를 사용할 수 있습니다.
has() {
local glob
for glob do
()(($#)) $~glob(NY1) && return
done
false
}
non_empty
( 익명 함수에도 인라인됩니다 .)
**/
재귀적 기능은 90년대 초반 zsh에서 제공되었으며 기본적으로 활성화되었습니다(bash에 의해 복사되었지만 2000년대 후반에는 기본적으로 활성화되지 않았습니다). 교체는 has 'foo/**/(bar|baz).xml'
in 으로 수행 됩니다 zsh
.
에서는 zsh
다음 작업도 수행할 수 있습니다.
alias has='noglob has'
할 수 있는 것:
if has foo/**/bar.xml foo/**/baz.xml; then
echo matches found
fi
글로벌 운영자를 인용할 필요가 없습니다.
답변2
위치 인수 목록을 재정의할 수 있는 경우:
shopt -s globstar nullglob
set -- foo/**/bar.xml foo/**/baz.xml
if [ "$#" -ne 0 ]; then
echo matches found
fi
이는 위치 매개변수 목록을 와일드카드 패턴과 일치하는 이름으로 설정합니다. 유효 하므로 nullglob
일치하는 항목이 없으면 목록은 비어 있습니다. 값은 $#
위치 인수 목록의 길이입니다.
서브셸에서 실행한다는 아이디어를 활용하세요.
( shopt -s globstar nullglob; set -- foo/**/bar.xml foo/**/baz.xml; [ "$#" -ne 0 ] )
위치 인수 목록 대신 배열을 사용하십시오.
shopt -s globstar nullglob
names=( foo/**/bar.xml foo/**/baz.xml )
if [ "${#names[@]}" -ne 0 ]; then
echo matches found
fi