Risposte:
Prova questo (non sono sicuro che sia il modo migliore, ma funziona):
find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
Funziona come segue:
git ls-tree -r HEAD --name-only
invece difind
find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort | uniq -c | sort -n
Non c'è bisogno che la pipe sort
lo faccia, Awk può fare tutto:
find . -type f | awk -F. '!a[$NF]++{print $NF}'
alias
riga con le virgolette per il comando ma il comando stesso utilizza già le virgolette nel comando find. Per risolvere questo problema, vorrei usare bash
la sintassi della stringa letterale in questo modo:alias file_ext=$'find . -type f -name "*.*" | awk -F. \'!a[$NF]++{print $NF}\''
maindir/test.dir/myfile
-printf "%f\n"
alla fine del comando 'trova' ed esegui nuovamente il test.
Versione ricorsiva:
find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort -u
Se vuoi i totali (come mai è stata vista l'estensione):
find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort | uniq -c | sort -rn
Non ricorsivo (cartella singola):
for f in *.*; do printf "%s\n" "${f##*.}"; done | sort -u
Ho basato questo su questo post sul forum , il merito dovrebbe andare lì.
git show --name-only --pretty="" | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort -u
PowerShell:
dir -recurse | select-object extension -unique
Grazie a http://kevin-berridge.blogspot.com/2007/11/windows-powershell.html
.
in loro (ad esempio jquery-1.3.4
verrà mostrato come .4
nell'output). Passare a dir -file -recurse | select-object extension -unique
per ottenere solo le estensioni dei file.
La mia alternativa compatibile con POSIX senza imbarazzo, senza sed, senza Perl, senza Python:
find . -type f | rev | cut -d. -f1 | rev | tr '[:upper:]' '[:lower:]' | sort | uniq --count | sort -rn
Il trucco è che inverte la linea e taglia l'estensione all'inizio.
Converte anche le estensioni in lettere minuscole.
Esempio di output:
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
non ha la bandiera completa --count
, ma -c
funziona benissimo
Trova tutto con un punto e mostra solo il suffisso.
find . -type f -name "*.*" | awk -F. '{print $NF}' | sort -u
se sai che tutti i suffissi hanno 3 caratteri allora
find . -type f -name "*.???" | awk -F. '{print $NF}' | sort -u
o con sed mostra tutti i suffissi con uno o quattro caratteri. Cambia {1,4} nell'intervallo di caratteri che ti aspetti nel suffisso.
find . -type f | sed -n 's/.*\.\(.\{1,4\}\)$/\1/p'| sort -u
Aggiungendo la mia variazione al mix. Penso che sia il più semplice del lotto e possa essere utile quando l'efficienza non è una grande preoccupazione.
find . -type f | grep -o -E '\.[^\.]+$' | sort -u
$ find . -type f | grep -o -E '\.[^.\/]+$' | sort -u
In Python usare generatori per directory molto grandi, incluse estensioni vuote, e ottenere il numero di volte in cui ogni estensione viene visualizzata:
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)
Ho provato un sacco di risposte qui, anche la risposta "migliore". Sono venuti tutti a corto di quello che stavo cercando. Quindi, oltre alle ultime 12 ore di seduta nel codice regex per più programmi e leggere e testare queste risposte, questo è quello che ho trovato che funziona ESATTAMENTE come voglio.
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort -u
Se è necessario un conteggio delle estensioni di file, utilizzare il codice seguente
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort | uniq -c | sort -rn
Sebbene questi metodi richiederanno del tempo per essere completati e probabilmente non sono i modi migliori per risolvere il problema, funzionano.
Aggiornamento: Per @ alpha_989 le estensioni di file lunghe causeranno un problema. Ciò è dovuto alla regex originale "[[: alpha:]] {3,6}". Ho aggiornato la risposta per includere il regex "[[: alpha:]] {2,16}". Tuttavia, chiunque utilizzi questo codice dovrebbe essere consapevole del fatto che quei numeri sono il minimo e il massimo di quanto tempo è consentito l'estensione per l'output finale. Qualunque cosa al di fuori di tale intervallo verrà suddivisa in più righe nell'output.
Nota: il post originale ha letto "- Greps per estensioni di file tra 3 e 6 caratteri (basta regolare i numeri se non si adattano alle tue necessità). Questo aiuta a evitare file di cache e file di sistema (il bit del file di sistema è di cercare jail). "
Idea: potrebbe essere utilizzato per trovare estensioni di file su una lunghezza specifica tramite:
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{4,}" | awk '{print tolower($0)}' | sort -u
Dove 4 è la lunghezza delle estensioni dei file da includere e quindi trovare anche eventuali estensioni oltre quella lunghezza.
Poiché esiste già un'altra soluzione che utilizza Perl:
Se hai installato Python potresti anche fare (dalla 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)"
Nessuna delle risposte finora tratta correttamente i nomi dei file con le nuove righe (tranne che per ChristopheD, che è appena arrivato mentre scrivevo). Quanto segue non è una shell one-liner, ma funziona ed è ragionevolmente veloce.
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
Non credo che questo sia stato ancora menzionato:
find . -type f -exec sh -c 'echo "${0##*.}"' {} \; | sort | uniq -c
L'ho trovato semplice e veloce ...
# 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 risposta accettata utilizza REGEX e non puoi creare un comando alias con REGEX, devi inserirlo in uno script di shell, sto usando Amazon Linux 2 e ho fatto quanto segue:
Ho inserito il codice di risposta accettato in un file usando:
sudo vim find.sh
aggiungi questo codice:
find ./ -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
salva il file digitando: :wq!
sudo vim ~/.bash_profile
alias getext=". /path/to/your/find.sh"
:wq!
. ~/.bash_profile
.svn
), utilizzare lafind . -type f -path '*/.svn*' -prune -o -print | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
fonte