web-dev-qa-db-ja.com

ディレクトリ内のファイルを拡張子でカウントする

テストの目的で、ディレクトリ内にある画像ファイルの数を数え、各画像ファイルタイプをファイル拡張子(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サイクルを使用する必要がありますか?

16
watchmansky

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[@]}$#"$@"に置き換えます

14
steeldriver

私のアプローチは:

  1. ディレクトリ内のすべてのファイルを一覧表示します
  2. 拡張子を抽出する
  3. 結果を並べ替える
  4. 各拡張子の出現回数を数える

このように並べ替えます(最後のawk呼び出しは純粋にフォーマット用です):

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

(GNU lsの場合、-U最適化としてソートをスキップするオプション。サポートされていない場合は、機能に影響を与えることなく安全に削除できます)。

26
groxxda

これは再帰的にファイルを走査し、一致する拡張子をカウントします:

$ 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
11
Kit
find -type f | sed -e 's/.*\.//' | sort | uniq -c
6
Neik

lsに関係するものはすべて、特殊文字(スペースおよびその他の記号)で予期しない結果をもたらす可能性があります。配列などのバシズムは移植できません。通常、while readに関連するものはすべて低速です。

一方、findは非常に柔軟性があり(フィルタリングするオプションがたくさんあります)、[少なくとも] 2つの構文があり、特殊文字に対してはフェイルセーフです。

この例では、-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

追伸-print0 | tr -d -c "\000" | wc -c-printf "\000" | wc -cまたは-printf '\n' | wc -lに置き換えることができます。

3
Franklin Piat

多分それは短くなることができます

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

合計を取得したいだけです。

find ./ -type f | sed -e 's/.*\.//' |  uniq -c | sort -u | awk '{print $1}' | awk '{total = total + $1}END{print total}'

出力:

2347623
0
Mike Q

この単純な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
0
Mike Q

拡張機能が確かな場合は、findのように

find *.jpeg | wc -l
0
Nithish JV