나는 이것 때문에 많은 어려움을 겪고 있습니다. 디렉터리에 특정 패턴과 일치하지 않는 파일이 있는지 테스트하려고 하며 true 또는 false를 반환합니다.
이 경우 $dir
파일이 밑줄로 시작하지 않는 경우 시도해 볼 것이라고 _
생각했습니다.if [ -f $dir/!(_*) ]
if [ $dir -f -name ! _* ]
또는
if ls $dir/!(_*) 1> /dev/null 2>&1
하지만 항상 말 Too many arguments
하거나syntax error near unexpected token "("
답변1
names=( "$dir"/[!_]* )
if [ -e "${names[0]}" ]; then
echo 'there are filenames that do not start with underscore'
printf '%d of them\n' "${#names[@]}"
fi
또는 그 문제에 대해 /bin/sh
( bash
그 문제에 대해):
set -- "$dir"/[!_]*
if [ -e "$1" ]; then
echo 'there are filenames that do not start with underscore'
printf '%d of them\n' "$#"
fi
즉, 적절한 와일드카드 패턴을 확장하고 그것이 존재하는 것과 일치하는지 테스트하십시오.
이 [!_]
패턴은 밑줄이 아닌 모든 문자와 일치합니다. 그것은 비슷하다정규식 [^_]
, 그러나 부정 문자 클래스 !
대신 파일 이름 글로빙 패턴이 사용됩니다 .^
언제 모드아니요일치하면 기본적으로 확장되지 않은 상태로 유지되므로 테스트를 사용하여 -e
일치 목록의 첫 번째 항목이 있는지 확인합니다. 반환된 목록의 길이를 실제로 테스트할 수는 없습니다. 길이가 1인 경우에도 여전히 어떤 것과도 일치하지 않을 수 있기 때문입니다( nullglob
에서 쉘 옵션을 설정하지 않는 한 bash
).
테스트하고 싶다면 조금 까다로워집니다.일반 파일특히 와일드카드 패턴이 일치하기 때문에어느이름(디렉터리, 일반 파일 및 기타 모든 유형의 파일) 하지만 이렇게 하면 다음과 같은 작업이 수행됩니다.
names=( "$dir"/[!_]* )
while [ "${#names[@]}" -gt 0 ] && [ ! -f "${names[0]}" ]; do
names=( "${names[@]:1}" )
done
if [ -f "${names[0]}" ]; then
echo 'there are at least one regular file here (or a symlink to one)'
echo 'whose filename does not start with underscore'
fi
또는 다음의 경우 /bin/sh
:
set -- "$dir"/[!_]*
while [ "$#" -gt 0 ] && [ ! -f "$1" ]; do
shift
done
if [ -f "$1" ]; then
echo 'there are at least one regular file here (or a symlink to one)'
echo 'whose filename does not start with underscore'
fi
이 방법은 또한 감지할 수 있습니다심볼릭 링크이름이 밑줄로 시작하지 않는 일반 파일로.
비정규 파일과 일치시킬 수 있는 파일 이름(예: 디렉터리 이름)을 제거하려면 루프가 필요합니다.
셸에서는 zsh
일치하는 항목이 있는 경우 일반 파일만 일치하도록 보장되는 패턴을 사용할 수 있습니다."$dir"/[^_]*(.)
더 복잡한 패턴의 경우 일치하는 항목 수를 일치하는 항목 수와 순진하게 비교할 수 있습니다 *
. 다르다면 복잡한 패턴과 맞지 않는 이름이 있는 것입니다.
에서는 bash
쉘 활성화 옵션을 사용한 후 확장 글로빙 모드를 사용할 수 있습니다. 일반적인 형태는 위와 같이 확장 결과를 확인하여 어떤 것으로든 확장되는지 확인해야 합니다.!(PATTERN)
extglob
shopt -s extglob
!(pattern1|pattern2|pattern3|etc)
밑줄로 시작하지 않는 이름의 예는 !(_*)
확장된 globbing 패턴을 사용할 수 있지만 이는 !(_)*
보이는 모든 이름과 일치하므로 작동하지 않는다는 점에 유의하세요 *
.