web-dev-qa-db-ja.com

ディレクトリ内の各拡張子のファイルの数を見つける

ディレクトリ内の各拡張子のファイルの数と、拡張子のないファイルの数を数えたい。

いくつかのオプションを試しましたが、まだ有効な解決策が見つかりませんでした。

  • find "$folder" -type f | sed 's/.*\.//' | sort | uniq -cはオプションですが、ファイル拡張子がない場合は機能しません。拡張子のないファイルの数を知る必要があります。

  • 私はまた、配列への検索ループを試みて結果を合計しましたが、この時点でコードは宣言されていない変数エラーをスローしますが、ループの外でのみ:

    declare -a arr
    arr=()
    echo ${arr[@]}
    

    これにより、未宣言の変数がスローされます。また、検索ループが完了するとスローされます。

9
tractor boy
find "$path" -type f | sed -e '/.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/' -e 's/.*\.//' | LC_COLLATE=C sort | uniq -c

説明:

  • find "$path" -type f"$path"フォルダー上のすべてのファイルの再帰的なリストを取得します。
  • sed -e '/.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/' -e 's/.*\.//'正規表現:
    • /.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/拡張子のないすべてのファイルを(なし)で置き換えます。
    • s/.*\.//残りのファイルの拡張子を取得します。
  • LC_COLLATE=C sort結果をソートし、シンボルを一番上に保ちます。
  • uniq -c繰り返しエントリの数をカウントします。
9
Helio

Pythonの使用:

import os
from collections import Counter
from pprint import pprint

lst = []
for file in os.listdir('./'):
        name, ext = os.path.splitext(file)
        lst.append(ext)

pprint(Counter(lst))

出力:

Counter({'': 7,
         '.png': 4,
         '.mp3': 3,
         '.jpg': 3,
         '.mkv': 3,
         '.py': 1,
         '.swp': 1,
         '.sh': 1})
9
Ravexina

GNU awkがあれば、次のようなことができます。

printf '%s\0' * | gawk 'BEGIN{RS="\0"; FS="."; OFS="\t"} 
  {a[(NF>1 ? $NF : "(none)")]++} 
  END{for(i in a) print a[i],i}
'

つまり、最後の.で区切られたフィールドをキーとする連想配列、または拡張子がない場合は(none)などの任意の固定文字列を構築/インクリメントします。

mawkはヌルバイトのレコード区切り文字を許可しないようです。ファイル名の改行を処理する必要がないと確信している場合は、mawkをデフォルトの改行区切り文字とともに使用できます。

printf '%s\n' * | mawk 'BEGIN{FS="."; OFS="\t"} {a[(NF>1 ? $NF : "(none)")]++} END{for(i in a) print a[i],i}'
6
steeldriver

基本的な/bin/shまたはbashでさえ、タスクは少し難しい場合がありますが、他の回答でわかるように、集計データを処理できるツールはそのようなタスクを特に簡単に処理できます。そのようなツールの1つは、sqliteデータベースです。

sqliteデータベースを使用する非常に簡単なプロセスは、ファイル名と拡張子の2つのフィールドを持つ.csvファイルを作成することです。後でsqliteGROUP BY extで簡単な集約ステートメントCOUNT()を使用して、拡張子フィールドに基づいてファイルのカウントを実行できます

$ { printf "file,ext\n"; find -type f -exec sh -c 'f=${1##*/};printf "%s,%s\n" "${1}" "${1##*.}"' sh {} \; ; }  > files.csv
$ sqlite3 <<EOF
> .mode csv
> .import ./files.csv files_tb
> SELECT ext,COUNT(file) FROM files_tb GROUP BY ext;
> EOF
csv,1
mp3,6
txt,1
wav,27
5

PowerShell を使用する(オプションの場合):

Get-ChildItem -File | Group-Object Extension -NoElement

以下を使用して、エイリアスを使用します。

ls -file | group -n Extension
5
Joey