테스트 목적으로 각 이미지 파일 형식을 파일 확장자(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
이 작업을 수행하려면 루프를 사용해야 합니까?
답변1
내 접근 방식은 다음과 같습니다
- 디렉토리의 모든 파일 나열
- 확장자를 추출하세요
- 결과 정렬
- 각 확장자의 발생 횟수를 계산합니다.
다음과 같습니다(마지막 awk
호출은 순전히 서식 지정을 위한 것입니다).
ls -q -U | awk -F . '{print $NF}' | sort | uniq -c | awk '{print $2,$1}'
ls
-U
( 최적화를 위해 여기에서 정렬을 건너뛰는 GNU 옵션이 있다고 가정합니다 . 지원되지 않는 경우 기능에 영향을 주지 않고 안전하게 제거할 수 있습니다.)
답변2
이는 파일을 반복적으로 반복하고 일치하는 확장자를 계산합니다.
$ 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
답변3
가능한 단어 분할 문제를 피하기 위해 다른 접근 방식을 제안하고 싶습니다.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[@]}
하고$#
"$@"
답변4
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