특정 파일 유형 / 확장자가 디렉토리에 있는지 확인


84

bash를 사용하여 특정 확장의 파일이 디렉토리에 있는지 여부를 어떻게 알 수 있습니까?

같은 것

if [ -e *.flac ]; then 
echo true; 
fi 

답변:


104
#!/bin/bash

count=`ls -1 *.flac 2>/dev/null | wc -l`
if [ $count != 0 ]
then 
echo true
fi 

9
토마스, 그냥 반대표 대신 질문에 더 나은 해결책을 추가하는 건 어떨까요?
JeremyWeir

8
또한 Thomas, 사용하지 않는 이유에 대한 예 ls -lls -1
는를

10
그리고이 대답은 출력을 파싱하는 것이 아니라 출력 된 줄을 세는 것뿐입니다. 파일 이름에 이상한 문자가 있어도 ls -1파일 당 한 줄을 인쇄 할 것이라고 거의 확신 합니다
JeremyWeir

2
라인 계산 구문 분석입니다. 그리고 파일에 잘못된 숫자가 반환됩니다 \n(예, 파일 이름에 유효 함).
marcelm

1
그러면 줄 수를 없애기 위해 파일 이름에 어떤 마법의 캐릭터가 있어야할까요?
여만

27
#/bin/bash

myarray=(`find ./ -maxdepth 1 -name "*.py"`)
if [ ${#myarray[@]} -gt 0 ]; then 
    echo true 
else 
    echo false
fi

5
당신이 실제로 할 수 있기 때문에이 사람은 좋은 어떻게 당신이 그들을 발견 후 파일 뭔가를.
ephsmith

myarray를 배열 변수로 만들기 위해 괄호 안에 find를 실행하는 서브 쉘을 감싸는 경우 +1. 그렇지 않은 경우 찾기 반환하지 결과는 ${#myarray[@]}1에 해당하지 않습니다
shaffooo

또한 사용하여 단순화 할 수 ls -1 *.py대신 발견의
JrBenito

이름에 공백이있는 파일이 있으면 하나의 인스턴스를 두 개로 계산합니다.
Jon Griffith

16

이것은 ls (1)을 사용합니다. flac 파일이 없으면 ls는 오류를보고하고 스크립트는 종료됩니다. 그렇지 않으면 스크립트가 계속되고 파일이 처리 될 수 있습니다.

#! /bin/sh
ls *.flac  >/dev/null || exit
## Do something with flac files here

4
추가 침묵을 위해 2> & 1도 리디렉션합니다.
Jasper

6
if 버전 :if ls *.flac >/dev/null 2>&1; then ... fi;
Josiah Yoder


4

당신은 당신이 당신의 if 진술에 그것이 당신이 원하는 결과와 어떤 관련이 있는지주의해야합니다.

다른 유형의 파일 시스템 항목이 아닌 일반 파일 만 확인하려면 코드 스켈레톤을 다음과 같이 변경해야합니다.

if [ -f file ]; then
echo true;
fi

의 사용 은를 일반 파일로 -f제한하는 if반면, -e더 광범위하며 모든 유형의 파일 시스템 항목과 일치합니다. 물론 -d디렉토리 와 같은 다른 옵션도 있습니다 . 좋은 목록 은 http://tldp.org/LDP/abs/html/fto.html 을 참조 하십시오.

@msw가 지적했듯이 test(즉 [) 두 개 이상의 인수를 제공하려고하면 질식합니다. 이는 glob이 *.flac둘 이상의 파일 을 반환 하는 경우 귀하의 경우에 발생할 수 있습니다 . 이 경우 if테스트를 다음과 같은 루프로 래핑하십시오 .

for file in ./*.pdf
do
    if [ -f "${file}" ]; then
    echo 'true';
    break
    fi
done

이렇게 break하면 원하는 파일 확장자의 첫 번째 인스턴스를 사용하고 나머지 스크립트를 계속 사용할 수 있습니다.


1
test(일명 [) 패턴이 둘 이상의 파일로 확장되는 경우를 제외하고 "이진 연산자가 예상 됨"또는 "너무 많은 인수"
msw

1
@msw-고마워, 그 문제에 대해 생각조차하지 못했습니다. 나는 그것을 고려하기 위해 내 대답을 수정하려고했습니다.
dtlussier 2010 년

"$file"파일 이름에 공백이나 별표와 같은 일부 잘못된 문자가 포함될 수 있으므로 변수를 따옴표로 묶어야합니다 ( 예 : use ).
Roman Cheplyaka 2010 년

3
#!/bin/bash
files=$(ls /home/somedir/*.flac 2> /dev/null | wc -l)
if [ "$files" != "0" ]
then
echo "Some files exists."
else
echo "No files with that extension."
fi

3

최고의 솔루션 (if [ -e *.flac ];)은 나를 위해 작동하지 않았습니다.[: too many arguments

if ls *.flac >/dev/null 2>&1; 그러면 작동합니다.


3

-f를 사용하여 특정 유형의 파일이 있는지 확인할 수 있습니다.

#!/bin/bash

if [ -f *.flac ] ; then
   echo true
fi 

이것은 작동하지만 당신은 lede를 묻고 있습니다- 그것이 작동 하는 이유[(보다 일반적인 것과 달리) 단일 브레이스 [[가 글 로빙을 방지하지 않기 때문입니다.
아드리안 페트 레스 쿠

2
   shopt -s nullglob
   set -- $(echo *.ext)
    if [ "${#}" -gt 0 ];then
      echo "got file"
    fi

이것은 잘못되었습니다. 첫째, -ge대신을 의미했을 것입니다. -gt그렇지 않으면 코드가 단일 파일을 감지하지 못하기 때문입니다. 두 번째로, 패턴과 일치하는 파일이없는 경우 일치하는 쉘은 문자열을 *.ext그대로 유지하므로 여전히 하나의 "결과"를 얻을 수 있습니다.
Roman Cheplyaka 2010 년

$ #은 단일 파일의 경우 1이고 파일이없는 경우 0입니다.
frayser

1

bash 전용 :

any_with_ext () ( 
    ext="$1"
    any=false
    shopt -s nullglob
    for f in *."$ext"; do
        any=true
        break
    done
    echo $any 
)

if $( any_with_ext flac ); then
    echo "have some flac"
else 
    echo "dir is flac-free"
fi

중괄호 대신 괄호를 사용하여 하위 셸이 사용되는지 확인합니다 (현재 nullglob설정 을 방해하고 싶지 않음 ).


1

다음은 외부 명령 (예 : no ls)을 사용하지 않고 대신 쉘 함수를 사용하는 솔루션 입니다. bash에서 테스트되었습니다.

shopt -s nullglob
function have_any() {
    [ $# -gt 0 ]
}

if have_any ./*.flac; then
    echo true
fi

함수 have_any$#인수를 계산하는 데 사용 하고 인수 [ $# -gt 0 ]가 하나 이상 있는지 테스트합니다. 의 사용은 ./*.flac단지 대신 *.flac에 호출은 have_any같은 이름을 가진 파일로 인한 문제를 방지하는 것입니다 --help.


1

완료하려면 zsh를 사용하십시오.

if [[ -n *.flac(#qN) ]]; then
  echo true
fi

이것은 zsh 매뉴얼 의 조건식 섹션 끝에 나열되어 있습니다. [[파일명 globbing을 비활성화 하기 때문에 (#q)globbing 문자열의 끝에 사용하여 파일명 생성을 강제해야 합니다. 그런 다음 N플래그 ( NULL_GLOB옵션)를 사용하여 일치하지 않는 경우 생성 된 문자열을 강제로 비워야합니다.


1

다음은 매우 간단한 해결책입니다.

if [ "$(ls -A | grep -i \\.flac\$)" ]; then echo true; fi

보시다시피 이것은 한 줄의 코드에 불과하지만 충분히 잘 작동합니다. bash 및 dash와 같은 posix 호환 쉘 모두에서 작동해야합니다. 또한 대소 문자를 구분하지 않으며 어떤 유형의 파일 (일반, 심볼릭 링크, 디렉토리 등)이 있는지 상관하지 않습니다. 심볼릭 링크 등이있는 경우 유용 할 수 있습니다.


ls -AR이 재귀 검색을 수행하기 때문에 이것을 좋아합니다. 압축을 푼 후 zip 아카이브의 내용을 검색하는 데 좋습니다.
justin cress

0

나는 이것을 시도했다 :

if [ -f *.html ]; then
    echo "html files exist"
else
    echo "html files dont exist"
fi

다른 파일에는 문제없이이 코드를 사용했지만 html 파일의 경우 오류가 발생했습니다 .

[: too many arguments

그런 다음 @JeremyWeir의 카운트 솔루션을 사용해 보았습니다.

루프에서이 작업을 수행하는 경우 카운트를 재설정해야합니다.

count=$((0))

0

이것은 모든 borne-like shell에서 작동합니다.

if [ "$(find . -maxdepth 1 -type f | grep -i '.*\.flac$')" ]; then
    echo true
fi

이것은 GNU에서도 작동 find하지만 다음과 같은 다른 구현과 호환되는 경우 IDK입니다 find.

if [ "$(find . -maxdepth 1 -type f -iname \*.flac)" ]; then
    echo true
fi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.