¿Cómo puedo encontrar todas las extensiones de archivo distintas en una jerarquía de carpetas?
-
12-09-2019 - |
Pregunta
En una máquina Linux quisiera atravesar una jerarquía de carpetas y obtener una lista de todas las extensiones de archivo distintas dentro de la misma.
¿Cuál sería la mejor manera de lograr esto de una concha?
Solución
Probar (no estoy seguro si es la mejor manera, pero funciona):
find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
funciona de la siguiente manera:
- Para todos los archivos de la carpeta actual
- Las impresiones extensión de los archivos en su caso
- Haga una lista ordenada único
Otros consejos
No hay necesidad de que la tubería sort
, awk puede hacerlo todo:
find . -type f | awk -F. '!a[$NF]++{print $NF}'
versión recursiva:
find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort -u
Si desea totales (cómo pueden veces la extensión fue visto):
find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort | uniq -c | sort -rn
No-recursivo (carpeta individual):
for f in *.*; do printf "%s\n" "${f##*.}"; done | sort -u
Me he basado en este este mensaje del foro , el crédito debe ir allí.
Powershell:
dir -recurse | select-object extension -unique
Gracias a http://kevin-berridge.blogspot.com/ 2007/11 / windows-powershell.html
Encuentra everythin con un punto y mostrar sólo el sufijo.
find . -type f -name "*.*" | awk -F. '{print $NF}' | sort -u
Si usted sabe todo sufijo tener 3 caracteres a continuación
find . -type f -name "*.???" | awk -F. '{print $NF}' | sort -u
o con espectáculos de sed todos los sufijos de uno a cuatro caracteres. Cambio {1,4} para el rango de caracteres que usted está esperando en el sufijo.
find . -type f | sed -n 's/.*\.\(.\{1,4\}\)$/\1/p'| sort -u
La adición de mi propia variación a la mezcla. Creo que es el más simple de la parcela y puede ser útil cuando la eficiencia no es una gran preocupación.
find . -type f | grep -o -E '\.[^\.]+$' | sort -u
Mi-awk menos, sed-menos, Perl-menos, Python-alternativa menos compatible con POSIX:
find . -type f | rev | cut -d. -f1 | rev | tr '[:upper:]' '[:lower:]' | sort | uniq --count | sort -rn
El truco es que invierte la línea y corta la ampliación a principios.
También convierte las extensiones a minúsculas.
Ejemplo de salida:
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
En Python usando generadores de directorios muy grandes, incluyendo las extensiones en blanco, y obtener el número de veces que cada extensión aparece:
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)
He intentado un montón de las respuestas aquí, incluso la "mejor" respuesta. Todos ellos se quedaron cortos de lo que era específicamente después. Así que además de las últimas 12 horas de estar sentado en el código expresiones regulares para múltiples programas y la lectura y probar estas respuestas esto es lo que ocurrió con la que funciona exactamente igual que yo quiero.
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort -u
- Busca todos los archivos que pueden tener una extensión.
- GREPS sólo la extensión
- GREPS para extensiones de archivo entre 2 y 16 caracteres (solo ajustar los números si no se ajustan a sus necesidades). Esto ayuda a evitar los archivos de caché y archivos del sistema de archivos del sistema (BIT es buscar en la cárcel).
- Awk para imprimir las extensiones en minúsculas.
- Ordenar y traer sólo valores únicos. En principio había intentado probar la respuesta awk pero sería el doble de elementos de impresión que variaban en mayúsculas y minúsculas.
Si necesita un recuento de las extensiones de archivo a continuación, utilizar el siguiente código
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort | uniq -c | sort -rn
Si bien estos métodos tomará algún tiempo para completar y probablemente no son los de las mejores maneras de ir sobre el problema, funcionan.
Actualización: Por @ alpha_989 extensiones de archivo largos causará un problema. Esto se debe a la expresión regular original de "[[: alpha:]] {3,6}". He actualizado la respuesta para incluir la expresión regular "[[: alpha:]] {2,16}". Sin embargo cualquier persona que utilice este código debe ser consciente de que esos números son los valores mínimo y máximo de cuánto tiempo se permite la extensión de la salida final. Cualquier cosa fuera de ese rango se dividirá en varias líneas en la salida.
Nota:. Original el correo leyó "- GREPS para extensiones de archivo entre los 3 y 6 caracteres (solo ajustar los números si no se ajustan a sus necesidades) Esto ayuda a evitar que los archivos de caché y archivos del sistema de archivos del sistema (BIT es la búsqueda cárcel). "
Idea: Podría ser usada para encontrar las extensiones de archivo en una longitud específica a través de:
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{4,}" | awk '{print tolower($0)}' | sort -u
¿Dónde 4 es la longitud de las extensiones de archivo para incluir y luego encontrar también cualquier extensión más allá de esa longitud.
Desde ya hay otra solución que utiliza Perl:
Si tiene instalado Python también se puede hacer (a partir de la cáscara):
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)"
Ninguna de las respuestas hasta el momento tratar con nombres de archivo con las nuevas líneas correctamente (excepto de ChristopheD, que acaba de llegar cuando estaba escribiendo esto). La siguiente no es una concha de una sola línea, pero funciona, y es razonablemente rápido.
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
No creo que éste fue mencionado todavía:
find . -type f -exec sh -c 'echo "${0##*.}"' {} \; | sort | uniq -c
Creo que la manera más sencilla y directa es
for f in *.*; do echo "${f##*.}"; done | sort -u
Se modificó el 3 de forma de ChristopheD.
También puede hacer esto
find . -type f -name "*.php" -exec PATHTOAPP {} +