Jak mogę znaleźć wszystkie odrębne rozszerzenia plików w hierarchii folderów?

Na Komputerze z Linuksem chciałbym przejść przez hierarchię folderów i uzyskać listę wszystkich odrębnych rozszerzeń plików w nim.

Jaki byłby najlepszy sposób na osiągnięcie tego z powłoki?

Author: GloryFish, 2009-12-03

13 answers

Spróbuj tego (nie wiem, czy to najlepszy sposób, ale działa):

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

Działa w następujący sposób:

  • Znajdź wszystkie pliki z bieżącego folderu
  • wyświetla rozszerzenie plików, jeśli istnieje
  • Stwórz unikalną posortowaną listę
 258
Author: Ivan Nevostruev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-03 19:27:33

No need for the pipe to sort, awk can do it all:

find . -type f | awk -F. '!a[$NF]++{print $NF}'
 36
Author: SiegeX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-10 20:18:14

Wersja rekurencyjna:

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

If you want totals (how may times the extension was seen):

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

Non-recursive (single folder):

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

Oparłem to na Ten post na forum, kredyt powinien tam trafić.

 22
Author: ChristopheD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-01 02:08:18

Powershell:

dir -recurse | select-object extension -unique

Dzięki http://kevin-berridge.blogspot.com/2007/11/windows-powershell.html

 17
Author: Simon R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-01 02:06:57

Znajdź everythin z kropką i Pokaż tylko przyrostek.

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

Jeśli wiesz, że wszystkie przyrostki mają 3 znaki to

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

Lub z sed pokazuje wszystkie sufiksy z jednym do czterech znaków. Zmień {1,4} na zakres znaków, których oczekujesz w sufiksie.

find . -type f | sed -n 's/.*\.\(.\{1,4\}\)$/\1/p'| sort -u
 10
Author: user224243,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-03 21:47:59

Dodanie własnej wariacji do miksu. Myślę, że jest najprostszy z wielu i może być przydatny, gdy wydajność nie jest wielkim problemem.

find . -type f | grep -o -E '\.[^\.]+$' | sort -u
 6
Author: gkb0986,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-09 17:38:50

Próbowałem kilka odpowiedzi tutaj, nawet "najlepsza" odpowiedź. Wszystkim zabrakło tego, o co mi chodziło. Więc oprócz ostatnich 12 godzin siedzenia w kodzie regex dla wielu programów i czytania i testowania tych Odpowiedzi to jest to, co wymyśliłem, który działa dokładnie tak, jak chcę.

 find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort -u
  • znajduje wszystkie pliki, które mogą mieć rozszerzenie.
  • Greps tylko rozszerzenie
  • Greps dla rozszerzeń plików od 2 do 16 znaków (po prostu dostosuj liczby, jeśli nie pasują do Twoich potrzeb). Pomaga to uniknąć plików pamięci podręcznej i plików systemowych(bit pliku systemowego jest do przeszukiwania).
  • Awk, aby wydrukować rozszerzenia małymi literami.
  • Sortuj i wprowadzaj tylko unikalne wartości. Początkowo próbowałem spróbować odpowiedź awk, ale to dwukrotnie drukować elementy, które różnią się wrażliwością na wielkość liter.

Jeśli potrzebujesz liczby rozszerzeń plików, użyj poniższego kodu

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

Podczas gdy te metody zajmie trochę czasu, aby zakończyć i prawdopodobnie nie są najlepsze sposoby na rozwiązanie problemu, działają.

Update: Na @ alpha_989 długie rozszerzenia plików będą powodować problem. Jest to spowodowane oryginalnym regex "[[: alpha:]] {3,6}". Zaktualizowałem odpowiedź o wyrażenie regularne " [[: alpha:]] {2,16}". Jednak każdy, kto używa tego kodu powinien być świadomy, że te liczby są min i max jak długo rozszerzenie jest dozwolone dla końcowego wyjścia. Wszystko poza tym zakresem zostanie podzielone na wiele linii w wyjściu.

Uwaga: Oryginał post did read " - Greps dla rozszerzeń plików od 3 do 6 znaków (po prostu dostosuj liczby, jeśli nie pasują do Twoich potrzeb). Pomaga to uniknąć plików pamięci podręcznej i plików systemowych(bit pliku systemowego jest do przeszukiwania)."

Idea: może być używana do wyszukiwania rozszerzeń plików o określonej długości poprzez:

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

Gdzie 4 to długość rozszerzenia pliku do włączenia, a następnie znajdź również wszelkie rozszerzenia powyżej tej długości.

 5
Author: Shinrai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 00:37:40

W Pythonie korzystanie z generatorów dla bardzo dużych katalogów, w tym pustych rozszerzeń, i uzyskanie liczby razy każde rozszerzenie pojawia się:

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)
 4
Author: Andres Buritica,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-16 05:34:54

Ponieważ istnieje już inne rozwiązanie, które używa Perla:

Jeśli masz zainstalowany Python możesz również zrobić (z powłoki):

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)"
 2
Author: ChristopheD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-04 08:27:53

Żadna z odpowiedzi do tej pory nie odnosi się poprawnie Do nazw plików z nowymi liniami (z wyjątkiem ChristopheD ' s, które właśnie przyszło, gdy pisałem to). Poniżej nie jest to powłoka jednowarstwowa, ale działa i jest dość szybka.

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
 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-04 08:35:28

Możesz też to zrobić

find . -type f -name "*.php" -exec PATHTOAPP {} +
 0
Author: jrock2004,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-25 17:27:04

Myślę, że najprostszym i najprostszym sposobem jest

for f in *.*; do echo "${f##*.}"; done | sort -u
/ Align = "left" /
 0
Author: Robert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-13 08:21:45

Chyba jeszcze o tym nie wspomniano:

find . -type f -exec sh -c 'echo "${0##*.}"' {} \; | sort | uniq -c
 0
Author: Dmitry B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-21 23:01:17