확장자로 디렉토리의 파일 수 디렉토리 내에 몇 개의 이미지

테스트 목적으로, 각 이미지 파일 유형을 파일 확장자 (jpg = “yes”)로 구분하여 디렉토리 내에 몇 개의 이미지 파일이 있는지 계산하고 싶습니다. 나중에 작업을 실행하는 다른 스크립트에 유용하기 때문에 각 파일 확장자). JPEG 파일에만 다음과 같은 것을 사용할 수 있습니까?

jpg=""
count=`ls -1 *.jpg 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo jpg files found: $count ; jpg="yes"
fi

jpg, png, bmp, raw 등의 파일 확장자를 고려할 때 while주기를 사용해야 합니까?



답변

가능한 단어 분리 문제를 피하면서 다른 접근법을 제안합니다. ls

#!/bin/bash

shopt -s nullglob

for ext in jpg png gif; do
  files=( *."$ext" )
  printf 'number of %s files: %d\n' "$ext" "${#files[@]}"

  # now we can loop over all the files having the current extension
  for f in "${files[@]}"; do
    # anything else you like with these files
    :
  done

done

files각 특정 확장자의 파일에 대해 수행하려는 다른 명령으로 배열을 반복 할 수 있습니다 .


더 이식 가능하거나 명시 적으로 배열을 제공하지 않는 쉘의 경우 쉘의 위치 매개 변수 배열을 다시 사용할 수 있습니다.

set -- *."$ext"

다음 교체 ${#files[@]}${files[@]}$#"$@"


답변

내 접근 방식은 다음과 같습니다.

  1. 디렉토리의 모든 파일을 나열하십시오.
  2. 그들의 확장을 추출
  3. 결과 정렬
  4. 각 확장의 발생 횟수 계산

이런 종류의 (마지막 awk호출은 순전히 형식화를위한 것입니다) :

ls -q -U | awk -F . '{print $NF}' | sort | uniq -c | awk '{print $2,$1}'

( 최적화로 정렬을 건너 뛰는 옵션에 ls대해 GNU를 여기에서 가정 -U합니다. 지원되지 않는 경우 기능에 영향을주지 않고 안전하게 제거 할 수 있습니다).


답변

이것은 재귀 적으로 파일을 순회하고 다음과 일치하는 확장자를 계산합니다.

$ find . -type f | sed -e 's/.*\.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'
   6 tiff
   7 bmp
  26 jpeg
  38 gif
  51 jpg
  54 png


답변

find -type f | sed -e 's/.*\.//' | sort | uniq -c


답변

어쩌면 더 짧아 질 수 있습니다

exts=( *.jpg *.png *.gif ); printf "There are ${#exts[@]}" extensions;


답변

관련 뭐든지 ls특수 문자 (공간과 다른 기호)와 예기치 않은 결과가 발생할 가능성이 높습니다. 배열과 같은 모든 bashism은 이식성이 없습니다. while read일반적으로 관련된 것은 느립니다.

다른 한편으로, find매우 유연하고 (여러 가지 옵션으로 필터링 할 수 있음), 특수 문자에는 실패 할 수있는 적어도 두 가지 구문이 있습니다. 큰 디렉토리에서 잘 확장됩니다.

이 예제에서는 -iname대문자와 소문자 확장명을 모두 사용 했습니다. 또한 -maxdepth 1귀하의 질문의 “현재 디렉토리”를 존중하도록 제한했습니다 . 파일 이름에 CR / LF가 포함될 수있는 줄 수를 계산하는 대신 -print0각 파일 이름 끝에 NULL 바이트를 인쇄합니다. 따라서 | tr -d -c "\000" | wc -l파일을 정확하게 계산하는 것입니다 (NULL 바이트!).

extensions="jpg png gif"
for ext in $extensions; do
  c=$(find . -maxdepth 1 -iname "*.$ext" -print0 | tr -d -c "\000" | wc -c)
  if [ $c -gt 0 ]; then
    echo "Found $c  *.$ext files"

    find . -maxdepth 1 -iname "*.$ext" -print0 | xargs -0 -r -n1 DOSOMETHINGHERE
    # or #  find . -maxdepth 1 -iname "*.$ext" -exec "ls" "-l" "{}" ";"
  fi
done

PS -print0 | tr -d -c "\000" | wc -c-printf "\000" | wc -c또는 로 교체 할 수 있습니다 -printf '\n' | wc -l.


답변

이 간단한 IMO에 ls를 사용할 수 있습니다.

ls -l /opt/ssl/certs/*.pem | wc -l

또는

count=$(ls -l /some/folder/*.jpg | wc -l)

또는

ls *.{mp3,exe,mp4} 2>/dev/null | wc -l