Réponses:
Essayez ceci (je ne sais pas si c'est la meilleure façon, mais cela fonctionne):
find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
Cela fonctionne comme suit:
git ls-tree -r HEAD --name-only
place defind
find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort | uniq -c | sort -n
Pas besoin de tuyau sort
, awk peut tout faire:
find . -type f | awk -F. '!a[$NF]++{print $NF}'
alias
commande, mais la commande elle-même utilise déjà des guillemets dans la commande find. Pour résoudre ce problème, j'utiliserais bash
la syntaxe de chaîne littérale de:alias file_ext=$'find . -type f -name "*.*" | awk -F. \'!a[$NF]++{print $NF}\''
maindir/test.dir/myfile
-printf "%f\n"
à la fin de la commande 'find' et relancez votre test.
Version récursive:
find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort -u
Si vous voulez des totaux (combien de fois l'extension a-t-elle été vue):
find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort | uniq -c | sort -rn
Non récursif (dossier unique):
for f in *.*; do printf "%s\n" "${f##*.}"; done | sort -u
J'ai basé cela sur ce message sur le forum , le crédit devrait y aller.
git show --name-only --pretty="" | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort -u
Powershell:
dir -recurse | select-object extension -unique
Merci à http://kevin-berridge.blogspot.com/2007/11/windows-powershell.html
.
(par exemple, jquery-1.3.4
ils apparaîtront comme .4
dans la sortie). Changez pour dir -file -recurse | select-object extension -unique
obtenir uniquement les extensions de fichier.
Mon alternative sans souci, sans sed, sans Perl, sans Python, conforme à POSIX:
find . -type f | rev | cut -d. -f1 | rev | tr '[:upper:]' '[:lower:]' | sort | uniq --count | sort -rn
L'astuce est qu'elle inverse la ligne et coupe l'extension au début.
Il convertit également les extensions en minuscules.
Exemple de sortie:
3689 jpg
1036 png
610 mp4
90 webm
90 mkv
57 mov
12 avi
10 txt
3 zip
2 ogv
1 xcf
1 trashinfo
1 sh
1 m4v
1 jpeg
1 ini
1 gqv
1 gcs
1 dv
uniq
n'a pas le drapeau complet --count
, mais -c
fonctionne très bien
Trouvez tout avec un point et n'affichez que le suffixe.
find . -type f -name "*.*" | awk -F. '{print $NF}' | sort -u
si vous savez que tous les suffixes ont 3 caractères,
find . -type f -name "*.???" | awk -F. '{print $NF}' | sort -u
ou avec sed affiche tous les suffixes avec un à quatre caractères. Remplacez {1,4} par la plage de caractères attendue dans le suffixe.
find . -type f | sed -n 's/.*\.\(.\{1,4\}\)$/\1/p'| sort -u
Ajout de ma propre variation au mix. Je pense que c'est le plus simple du lot et peut être utile lorsque l'efficacité n'est pas une grande préoccupation.
find . -type f | grep -o -E '\.[^\.]+$' | sort -u
$ find . -type f | grep -o -E '\.[^.\/]+$' | sort -u
En Python, utiliser des générateurs pour de très gros répertoires, y compris des extensions vides, et obtenir le nombre de fois où chaque extension apparaît:
import json
import collections
import itertools
import os
root = '/home/andres'
files = itertools.chain.from_iterable((
files for _,_,files in os.walk(root)
))
counter = collections.Counter(
(os.path.splitext(file_)[1] for file_ in files)
)
print json.dumps(counter, indent=2)
J'ai essayé un tas de réponses ici, même la "meilleure" réponse. Ils sont tous restés en deçà de ce que je cherchais spécifiquement. Donc, en plus des 12 dernières heures passées en code regex pour plusieurs programmes et en lisant et en testant ces réponses, c'est ce que j'ai trouvé qui fonctionne exactement comme je le souhaite.
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort -u
Si vous avez besoin d'un nombre d'extensions de fichiers, utilisez le code ci-dessous
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort | uniq -c | sort -rn
Bien que ces méthodes prennent un certain temps à compléter et ne soient probablement pas les meilleures façons de résoudre le problème, elles fonctionnent.
Mise à jour: les extensions de fichier longues selon @ alpha_989 entraîneront un problème. Cela est dû à l'expression régulière "[[: alpha:]] {3,6}". J'ai mis à jour la réponse pour inclure l'expression régulière "[[: alpha:]] {2,16}". Cependant, toute personne utilisant ce code doit être conscient que ces nombres sont le minimum et le maximum de la durée pendant laquelle l'extension est autorisée pour la sortie finale. Tout ce qui est en dehors de cette plage sera divisé en plusieurs lignes dans la sortie.
Remarque: le message d'origine a lu "- Greps pour les extensions de fichier entre 3 et 6 caractères (ajustez simplement les nombres s'ils ne correspondent pas à vos besoins). Cela permet d'éviter les fichiers de cache et les fichiers système (le bit du fichier système est pour rechercher en prison). "
Idée: pourrait être utilisée pour trouver des extensions de fichier sur une longueur spécifique via:
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{4,}" | awk '{print tolower($0)}' | sort -u
Où 4 est la longueur des extensions de fichier à inclure, puis recherchez également toutes les extensions au-delà de cette longueur.
Puisqu'il existe déjà une autre solution qui utilise Perl:
Si vous avez installé Python, vous pouvez également faire (à partir du shell):
python -c "import os;e=set();[[e.add(os.path.splitext(f)[-1]) for f in fn]for _,_,fn in os.walk('/home')];print '\n'.join(e)"
Jusqu'à présent, aucune des réponses ne traite correctement des noms de fichiers avec des sauts de ligne (à l'exception de ChristopheD, qui vient d'arriver au moment où je tapais ceci). Ce qui suit n'est pas un one-liner shell, mais fonctionne et est assez rapide.
import os, sys
def names(roots):
for root in roots:
for a, b, basenames in os.walk(root):
for basename in basenames:
yield basename
sufs = set(os.path.splitext(x)[1] for x in names(sys.argv[1:]))
for suf in sufs:
if suf:
print suf
Je ne pense pas que celui-ci ait encore été mentionné:
find . -type f -exec sh -c 'echo "${0##*.}"' {} \; | sort | uniq -c
Je l'ai trouvé simple et rapide ...
# find . -type f -exec basename {} \; | awk -F"." '{print $NF}' > /tmp/outfile.txt
# cat /tmp/outfile.txt | sort | uniq -c| sort -n > tmp/outfile_sorted.txt
La réponse acceptée utilise REGEX et vous ne pouvez pas créer une commande d'alias avec REGEX, vous devez la mettre dans un script shell, j'utilise Amazon Linux 2 et j'ai fait ce qui suit:
Je mets le code de réponse accepté dans un fichier en utilisant:
sudo vim find.sh
ajoutez ce code:
find ./ -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
enregistrez le fichier en tapant: :wq!
sudo vim ~/.bash_profile
alias getext=". /path/to/your/find.sh"
:wq!
. ~/.bash_profile
.svn
), utilisezfind . -type f -path '*/.svn*' -prune -o -print | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
source