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.
find "$path" -type f | sed -e '/.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/' -e 's/.*\.//' | LC_COLLATE=C sort | uniq -c
find "$path" -type f
obtient 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 sort
trie le résultat en gardant les symboles en haut.uniq -c
comptez le nombre d'entrées répétées.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})
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}'
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
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