Как я могу найти все отдельные расширения файлов в иерархии папок?
На машине Linux я хотел бы пройти иерархию папок и получить список всех отдельных расширений файлов внутри нее.
Каким будет лучший способ добиться этого из оболочки?
Ответы
Ответ 1
Попробуйте (не уверен, что это лучший способ, но он работает):
find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
Он работает следующим образом:
- Найти все файлы из текущей папки
- Печать расширений файлов, если есть
- Создайте уникальный отсортированный список
Ответ 2
Нет необходимости в трубе до sort
, awk может сделать все:
find . -type f | awk -F. '!a[$NF]++{print $NF}'
Ответ 3
Рекурсивная версия:
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
Я основывал это на этот пост форума, кредит должен идти туда.
Ответ 4
Powershell:
dir -recurse | select-object extension -unique
Спасибо http://kevin-berridge.blogspot.com/2007/11/windows-powershell.html
Ответ 5
Найдите все с точкой и покажите только суффикс.
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\}\)$/\1/p'| sort -u
Ответ 6
Добавление моего собственного изменения в микс. Я думаю, что это самый простой из них и может быть полезен, когда эффективность не является большой проблемой.
find . -type f | grep -o -E '\.[^\.]+$' | sort -u
Ответ 7
Моя альтернатива, не требующая использования awk-менее, sed-less, Perl-менее и Python-совместимая:
find . -type f | rev | cut -d. -f1 | rev | tr '[:upper:]' '[:lower:]' | sort | uniq --count | sort -rn
Хитрость в том, что она переворачивает линию и обрезает расширение в начале.
Он также преобразует расширения в нижний регистр.
Пример вывода:
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
Ответ 8
В 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)
Ответ 9
Я попробовал кучу ответов здесь, даже самый лучший ответ. Все они не соответствовали тому, что я был конкретно после. Таким образом, помимо последних 12 часов сидения в коде регулярных выражений для нескольких программ, чтения и тестирования этих ответов, я пришел к тому, что работает ТОЧНО, как я хочу.
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort -u
- Находит все файлы, которые могут иметь расширение.
- Greps только расширение
- Greps для расширений файлов от 2 до 16 символов (просто измените числа, если они не соответствуют вашим потребностям). Это помогает избежать кеширования файлов и системных файлов (системный файл предназначен для поиска в тюрьме).
- Awk для печати расширений в нижнем регистре.
- Сортируйте и вносите только уникальные значения. Первоначально я пытался попробовать ответить на awk, но он удвоил бы печать элементов, которые варьировались в зависимости от регистра.
Если вам нужно количество расширений файлов, используйте приведенный ниже код
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort | uniq -c | sort -rn
Хотя выполнение этих методов займет некоторое время и, возможно, не является лучшим способом решения проблемы, они работают.
Обновление: для длинных расширений файлов @@_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($0)}' | sort -u
Где 4 - это длина расширений файла, которую нужно включить, а затем найти также любые расширения, превышающие эту длину.
Ответ 10
Поскольку уже существует другое решение, использующее 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)"
Ответ 11
Ни один из ответов до сих пор не соответствует именам файлов с новыми символами (за исключением ChristopheD, которые только что вошли, когда я печатал это). Следующее не является оболочкой однострочного, но работает и достаточно быстро.
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
Ответ 12
Я не думаю, что это было упомянуто еще:
find . -type f -exec sh -c 'echo "${0##*.}"' {} \; | sort | uniq -c
Ответ 13
Я думаю, что самый простой и простой способ
for f in *.*; do echo "${f##*.}"; done | sort -u
Это модифицировано на ChristopheD 3-й способ.
Ответ 14
вы также можете сделать это
find . -type f -name "*.php" -exec PATHTOAPP {} +