Подсчет нескольких файлов в каталоге с одинаковым именем

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

Проблема в том, что у меня есть папка с более чем 5000 файлами, многие из которых имеют одно и то же имя, но разные расширения. Я написал код, который в некоторой степени выполняет то, что я хочу сделать в окончательной версии, но он ОЧЕНЬ избыточен, и я не вижу, чтобы я делал это для более 600 имен файлов.

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

Пример кода, который у меня сейчас есть:

import os, sys
print(sys.version)

file_counting1 = 0
file_counting2 = 0

filepath = input("Enter file path here: ")

if os.path.exists(filepath):

    for file in os.listdir(filepath):
        if file.startswith('expressmail'):
            file_counting1 += 1
    print('expressmail')
    print('Total files found:', file_counting1)

    for file in os.listdir(filepath):
        if file.startswith('prioritymail'):
            file_counting2 += 1
    print('prioritymail')
    print('Total files found:', file_counting2)

Пример вывода:

expressmail
Total files found: 3
prioritymail
Total files found: 1

3 ответа

Следующий скрипт будет подсчитывать вхождения файлов с одинаковыми именами. Если файл не имеет расширения, все имя файла рассматривается как имя. Он также не пересекает подкаталоги, так как исходный вопрос просто спрашивает о файлах в данной папке.

import os

dir_name = "."
files = next(os.walk(dir_name))[2]  # get all the files directly in the directory
names = [f[:f.rindex(".")] for f in files if "." in f] # drop the extensions
names += [f for f in files if "." not in f] # add those without extensions
for name in set(names): # for each unique name-
    print("{}\nTotal files found: {}".format(name, names.count(name)))

Если вы хотите поддерживать файлы в подкаталогах, вы можете использовать что-то вроде

files = [os.path.join(r,file) for r,d,f in os.walk(dir_name) for file in f]

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

names += [f for f in files if "." not in f]

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

  1. Счетчик из модуля коллекций - используйте это для простого подсчета файлов. Игнорируйте расширения при построении счета.
  2. Используйте имя файла без расширения в качестве ключа словаря, добавьте список элементов в качестве значения ключа, где список элементов - это каждое вхождение файла.

Вот пример использования класса Counter:

import os, sys, collections
c = collections.Counter()
for root, dirs,files in os.walk('/home/myname/hg/2018/'):
    # discard any path data and just use filename
    for names in files:
        name, ext = os.path.splitext(names)
        # discard any extension
        c[name] += 1
# Counter.most_common() gives the values in the form of (entry, count)
# Counter.most_common(x) - pass a value to display only the top x counts
# e.g. Counter.most_common(2) = top 2
for x in c.most_common():
    print(x[0] + ': ' + str(x[1]))

Вы можете использовать регулярные выражения:

import os, sys, re
print(sys.version)


filepath = input("Enter file path here: ")

if os.path.exists(filepath):
    allfiles = "\n".join(os.listdir(filepath))

    file_counting1 = len(re.findall("^expressmail",allfiles,re.M))
    print('expressmail')
    print('Total files found:', file_counting1)

    file_counting2 = len(re.findall("^prioritymail",allfiles,re.M))
    print('prioritymail')
    print('Total files found:', file_counting2)
Другие вопросы по тегам