web-dev-qa-db-fra.com

Trouver le nombre de fichiers pour chaque extension dans un répertoire

Je veux compter le nombre de fichiers pour chaque extension dans un répertoire ainsi que les fichiers sans extension.

J'ai essayé quelques options, mais je n'ai pas encore trouvé de solution efficace:

  • find "$folder" -type f | sed 's/.*\.//' | sort | uniq -c est une option mais ne fonctionne pas s'il n'y a pas d'extension de fichier. J'ai besoin de savoir combien de fichiers n'ont pas d'extension.

  • J'ai également essayé une boucle de recherche dans un tableau, puis la somme des résultats, mais à ce stade, le code renvoie une erreur de variable non déclarée, mais uniquement en dehors de la boucle:

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

    Cela jette une variable non déclarée, ainsi qu'une fois la boucle de recherche terminée.

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

Explication:

  • find "$path" -type fobtient une liste récursive de tous les fichiers du dossier "$path".
  • sed -e '/.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/' -e 's/.*\.//'expressions régulières:
    • /.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/remplace tous les fichiers sans extension par (aucun).
    • s/.*\.//récupère l'extension des fichiers restants.
  • LC_COLLATE=C sorttrie le résultat en gardant les symboles en haut.
  • uniq -ccomptez le nombre d'entrées répétées.
9
Helio

Utiliser 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))

Le résultat:

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

Si vous avez GNU awk, vous pouvez faire quelque chose comme

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

c'est-à-dire construire/incrémenter un tableau associatif composé du dernier champ séparé . ou d'une chaîne fixe arbitraire telle que (none) s'il n'y a pas d'extension.

mawk ne semble pas autoriser un séparateur d'enregistrement à octets nuls - vous pouvez utiliser mawk avec le séparateur de nouvelle ligne par défaut si vous êtes certain de ne pas avoir à gérer les nouvelles lignes dans les noms de fichiers:

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

Avec /bin/sh ou même bash, la tâche peut être un peu difficile, mais comme vous pouvez le voir dans d’autres réponses, les outils qui peuvent fonctionner sur des données agrégées peuvent s’acquitter de cette tâche particulièrement facilement. Un de ces outils serait sqlite database.

Le processus très simple d'utilisation de la base de données sqlite consiste à créer un fichier .csv avec deux champs: nom de fichier et extension. Plus tard, sqlite peut utiliser la simple instruction d'agrégation COUNT() avec GROUP BY ext pour effectuer le comptage des fichiers en fonction du champ d'extension.

$ { 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

Utiliser PowerShell si c'est une option:

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

ou plus court, en utilisant des alias:

ls -file | group -n Extension
5
Joey