テスト目的で、各画像ファイルの種類をファイル拡張子(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
非常に柔軟で(フィルタリングオプションが多い)、[少なくとも]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