it-swarm.com.de

Wie finde ich alle unterschiedlichen Dateierweiterungen in einer Ordnerhierarchie?

Auf einem Linux-Computer möchte ich eine Ordnerhierarchie durchlaufen und eine Liste aller darin enthaltenen unterschiedlichen Dateierweiterungen erhalten.

Was wäre der beste Weg, dies von einer Shell aus zu erreichen?

207
GloryFish

Versuchen Sie dies (nicht sicher, ob es der beste Weg ist, aber es funktioniert):

find . -type f | Perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u

Es funktioniert wie folgt:

  • Finde alle Dateien aus dem aktuellen Ordner
  • Gibt die Dateierweiterung aus, falls vorhanden
  • Erstellen Sie eine eindeutige sortierte Liste
312
Ivan Nevostruev

Keine Notwendigkeit für die Pipe zu sort, awk kann alles:

find . -type f | awk -F. '!a[$NF]++{print $NF}'
45
SiegeX

Rekursive Version:

find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort -u

Wenn du Summen willst (wie darf mal die Nebenstelle gesehen werden):

find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort | uniq -c | sort -rn

Nicht rekursiv (einzelner Ordner):

for f in *.*; do printf "%s\n" "${f##*.}"; done | sort -u

Ich habe dies auf dieser Forumsbeitrag , Kredit sollte dort gehen.

34
ChristopheD

Power Shell:

dir -recurse | select-object extension -unique

Vielen Dank an http://kevin-berridge.blogspot.com/2007/11/windows-powershell.html

23
Simon R

Finde alles mit einem Punkt und zeige nur das Suffix.

find . -type f -name "*.*" | awk -F. '{print $NF}' | sort -u

wenn Sie wissen, dass alle Suffixe 3 Zeichen haben, dann

find . -type f -name "*.???" | awk -F. '{print $NF}' | sort -u

oder mit sed zeigt alle Suffixe mit ein bis vier Zeichen an. Ändern Sie {1,4} in den Zeichenbereich, den Sie im Suffix erwarten.

find . -type f | sed -n 's/.*\.\(.\{1,4\}\)$/\1/p'| sort -u
12
user224243

Hinzufügen meiner eigenen Variation zu der Mischung. Ich denke, es ist das einfachste und kann nützlich sein, wenn Effizienz keine große Rolle spielt.

find . -type f | grep -o -E '\.[^\.]+$' | sort -u
7
gkb0986

Meine awk-less, sed-less, Perl-less, Python-less POSIX-kompatible Alternative:

find . -type f | rev | cut -d. -f1 | rev  | tr '[:upper:]' '[:lower:]' | sort | uniq --count | sort -rn

Der Trick ist, dass es die Linie umkehrt und die Verlängerung am Anfang schneidet.
Es konvertiert auch die Erweiterungen in Kleinbuchstaben.

Beispielausgabe:

   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
6
Ondra Žižka

Wenn Sie Python mit Generatoren für sehr große Verzeichnisse, einschließlich leerer Erweiterungen, arbeiten und die Häufigkeit abrufen, mit der jede Erweiterung angezeigt wird:

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)
5
Andres Restrepo

Ich habe hier ein paar Antworten ausprobiert, sogar die "beste" Antwort. Sie alle haben nicht das erreicht, wonach ich speziell gesucht habe. Abgesehen von den letzten 12 Stunden, in denen ich in Regex-Code für mehrere Programme gesessen und diese Antworten gelesen und getestet habe, habe ich mir dies ausgedacht, was genau so funktioniert, wie ich es möchte.

 find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort -u
  • Findet alle Dateien, die eine Erweiterung haben können.
  • Greift nur die Nebenstelle
  • Sucht nach Dateierweiterungen zwischen 2 und 16 Zeichen (passen Sie die Zahlen einfach an, wenn sie nicht Ihren Anforderungen entsprechen). Dies hilft, Cache-Dateien und Systemdateien zu vermeiden (das Systemdateibit dient zur Suche im Gefängnis).
  • Awk, um die Erweiterungen in Kleinbuchstaben zu drucken.
  • Sortieren und nur eindeutige Werte einbringen. Ursprünglich hatte ich versucht, die Antwort awk auszuprobieren, aber es wurden doppelt so viele Elemente gedruckt, bei denen die Groß- und Kleinschreibung unterschiedlich war.

Wenn Sie die Anzahl der Dateierweiterungen benötigen, verwenden Sie den folgenden Code

find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort | uniq -c | sort -rn

Obwohl diese Methoden einige Zeit in Anspruch nehmen und wahrscheinlich nicht die besten Methoden sind, um das Problem zu lösen, funktionieren sie.

Update: Pro @ alpha_989 verursachen lange Dateierweiterungen ein Problem. Das liegt am ursprünglichen regulären Ausdruck "[[: alpha:]] {3,6}". Ich habe die Antwort aktualisiert, um den regulären Ausdruck "[[: alpha:]] {2,16}" aufzunehmen. Jeder, der diesen Code verwendet, sollte sich darüber im Klaren sein, dass diese Zahlen die Mindest- und Höchstdauer sind, für die die Erweiterung für die endgültige Ausgabe zulässig ist. Alles außerhalb dieses Bereichs wird in der Ausgabe in mehrere Zeilen aufgeteilt.

Hinweis: Der ursprüngliche Beitrag lautete "- Grept nach Dateierweiterungen zwischen 3 und 6 Zeichen (passen Sie die Zahlen einfach an, wenn sie nicht Ihren Anforderungen entsprechen.) Dies hilft, Cache-Dateien und Systemdateien zu vermeiden (das Systemdateibit dient zum Durchsuchen des Gefängnisses). "

Idee: Könnte verwendet werden, um Dateierweiterungen über eine bestimmte Länge zu finden:

 find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{4,}" | awk '{print tolower($0)}' | sort -u

Wobei 4 die Länge der Dateierweiterungen ist, die eingeschlossen werden sollen, und dann auch alle Erweiterungen finden, die diese Länge überschreiten.

5
Shinrai

Da es bereits eine andere Lösung gibt, die Perl verwendet:

Wenn Sie Python installiert haben, können Sie auch (aus der 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)"
3
ChristopheD

Ich glaube nicht, dass dieser schon erwähnt wurde:

find . -type f -exec sh -c 'echo "${0##*.}"' {} \; | sort | uniq -c
2
Dmitry B.

Keine der bisherigen Antworten befasst sich ordnungsgemäß mit Dateinamen mit Zeilenumbrüchen (mit Ausnahme von ChristopheDs, die gerade eingegangen sind, als ich dies eingetippt habe). Das Folgende ist kein Shell-Einzeiler, funktioniert aber und ist einigermaßen schnell.

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
2
user25148

Ich denke, der einfachste und direkteste Weg ist

for f in *.*; do echo "${f##*.}"; done | sort -u

Es wurde auf dem dritten Weg von ChristopheD modifiziert.

1
Robert

du könntest das auch tun

find . -type f -name "*.php" -exec PATHTOAPP {} +
0
jrock2004