拡張子でディレクトリ内のファイル数を計算する

拡張子でディレクトリ内のファイル数を計算する

テスト目的で、各画像ファイルの種類をファイル拡張子(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

私のアプローチは次のとおりです。

  1. ディレクトリ内のすべてのファイルのリスト
  2. 拡張子を抽出
  3. 結果の並べ替え
  4. 各拡張子の発生回数を計算します。

次のようになります(最後の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非常に柔軟で(フィルタリングオプションが多い)、[少なくとも]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

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

関連情報