Как я могу найти все отдельные расширения файлов в иерархии папок?

на машине Linux я хотел бы пересечь иерархию папок и получить список всех отдельных расширений файлов внутри нее.

каков был бы лучший способ достичь этого из оболочки?

13 ответов


попробуйте это (не уверен, если это лучший способ, но он работает):

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

Он работает следующим образом:

  • найти все файлы из текущей папки
  • печатает расширение файлов, если таковые имеются
  • сделать уникальный список отсортированных

отсутствие потребности для трубы к sort, на awk может сделать все это:

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

рекурсивная версия:

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

Если вы хотите итоги (как может раз расширение было замечено):

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

нерекурсивный (одна папка):

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

Я основал это на данное сообщение на форуме, кредит должен пойти туда.


Powershell:

dir -recurse | select-object extension -unique

спасибо http://kevin-berridge.blogspot.com/2007/11/windows-powershell.html


найти все с точкой и показать только суффикс.

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

Если вы знаете, что все суффиксы имеют 3 символа, то

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

или с sed показывает все суффиксы с одним до четырех символов. Измените {1,4} на диапазон символов, ожидаемых в суффиксе.

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

добавление моей собственной вариации в микс. Я думаю, что это самый простой и может быть полезно, когда эффективность не является большой проблемой.

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

Я перепробовал кучу ответов здесь, даже "лучший" ответ. Все они не дотягивали до того, что мне было нужно. Итак, помимо последних 12 часов сидения в коде регулярных выражений для нескольких программ и чтения и тестирования этих ответов, это то, что я придумал, что работает именно так, как я хочу.

 find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower()}' | sort -u
  • находит все файлы, которые могут иметь расширение.
  • Greps только расширение
  • Greps для расширений файлов от 2 до 16 символов (просто отрегулируйте номера, если они не соответствуют вашим потребностям). Это помогает избежать кэш-файлов и системных файлов (системный файл бит для поиска тюрьмы).
  • Awk для печати расширений в нижнем регистре.
  • сортировка и ввод только уникальных значений. Первоначально я попытался попробовать ответ awk, но он удвоил бы элементы печати, которые варьировались в зависимости от чувствительности к регистру.

Если вам нужно количество расширений файлов, используйте приведенный ниже код

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

пока эти методы потребуют некоторого времени для завершения и, вероятно, не являются лучшими способами решения проблемы, они работают.

обновление: Per @alpha_989 длинные расширения файлов вызовет проблему. Это связано с оригинальным регулярным выражением " [[: alpha:]] {3,6}". Я обновил ответ, чтобы включить регулярное выражение " [[: alpha:]] {2,16}". Однако любой, кто использует этот код, должен знать, что эти числа являются минимальными и максимальными, как долго расширение разрешено для окончательного вывода. Ничего за пределами этого диапазона будет разбита на несколько строк в выходных данных.

Примечание: Оригинальный пост прочитал " - Greps для расширений файлов между 3 и 6 символами (просто отрегулируйте номера, если они не соответствуют вашим потребностям). Это помогает избежать кэш-файлов и системных файлов (системный файл бит для поиска тюрьмы)."

идея: может использоваться для поиска расширений файлов определенной длины через:

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

где 4-Длина расширений файлов для включения, а затем найти также любые расширения за пределами этого длина.


в Python, используя генераторы для очень больших каталогов, включая пустые расширения, и получая количество раз, когда каждое расширение появляется:

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)

поскольку уже есть другое решение, которое использует Perl:

Если у Вас установлен Python, вы также можете сделать (из оболочки):

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)"

ни один из ответов до сих пор не имеет дело с именами файлов с новыми строками должным образом (за исключением Кристофеда, который только что вошел, когда я печатал это). Следующее не является оболочкой-вкладышем, но работает и достаточно быстро.

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

вы также можете сделать это

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

Я думаю, что самый простой и прямой способ-это

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

он изменен на 3-м пути Кристофеда.


Я не думаю, что это было упомянуто еще:

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