¿Cómo puedo encontrar todas las extensiones de archivo distintas en una jerarquía de carpetas?

StackOverflow https://stackoverflow.com/questions/1842254

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?

¿Fue útil?

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 {} +
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top