2009-11-09 3 views
1

Предположит, у меня есть такие папкиPython манипуляция файла

rootfolder 
     | 
    /\ \ 
    01 02 03 .... 
    | 
    13_itemname.xml 

Так под мой RootFolder, каждый каталог представляет собой месяц, как 01 02 03 и в этих каталогах у меня есть элементы с их созданием часов и пунктом названием таких как 16_item1 .xml, 24_item1.xml и т. д., так как вы можете догадаться, что есть несколько элементов и каждый xml создается каждый час.

Теперь я хочу сделать две вещи:

  • Мне нужно, чтобы создать список имен элементов, которые в течение месяца, то есть за 01 у меня есть item1, item2 и ITEM3 внутри.

  • Мне нужно отфильтровать каждый элемент, например, для item1: я хочу читать каждый из 01_item1.xml до 24_item1.xml.

Как я могу достичь их в Python в простой форме?

+0

Какой код у вас сейчас? Это не «написать мой код для me.com». Что вы пробовали? Когда вы посмотрели на «os.walk», что вы видели? –

ответ

5

Вот два способа делать то, что вы просите (если я правильно понял). Один с регулярным выражением, один без него. Вы выбираете, какой из них вы предпочитаете;)

Один бит, который может показаться волшебным, - это строка «setdefault». Для пояснения см. the docs. Я оставляю это как «упражнение для читателя», чтобы понять, как это работает;)

from os import listdir 
from os.path import join 

DATA_ROOT = "testdata" 

def folder_items_no_regex(month_name): 

    # dict holding the items (assuming ordering is irrelevant) 
    items = {} 

    # 1. Loop through all filenames in said folder 
    for file in listdir(join(DATA_ROOT, month_name)): 
     date, name = file.split("_", 1) 

     # skip files that were not possible to split on "_" 
     if not date or not name: 
     continue 

     # ignore non-.xml files 
     if not name.endswith(".xml"): 
     continue 

     # cut off the ".xml" extension 
     name = name[0:-4] 

     # keep a list of filenames 
     items.setdefault(name, set()).add(file) 

    return items 

def folder_items_regex(month_name): 

    import re 

    # The pattern: 
    # 1. match the beginnning of line "^" 
    # 2. capture 1 or more digits (\d+) 
    # 3. match the "_" 
    # 4. capture any character (as few as possible): (.*?) 
    # 5. match ".xml" 
    # 6. match the end of line "$" 
    pattern = re.compile(r"^(\d+)_(.*?)\.xml$") 

    # dict holding the items (assuming ordering is irrelevant) 
    items = {} 

    # 1. Loop through all filenames in said folder 
    for file in listdir(join(DATA_ROOT, month_name)): 

     match = pattern.match(file) 
     if not match: 
     continue 

     date, name = match.groups() 

     # keep a list of filenames 
     items.setdefault(name, set()).add(file) 

    return items 
if __name__ == "__main__": 
    from pprint import pprint 

    data = folder_items_no_regex("02") 

    print "--- The dict ---------------" 
    pprint(data) 

    print "--- The items --------------" 
    pprint(sorted(data.keys())) 

    print "--- The files for item1 ---- " 
    pprint(sorted(data["item1"])) 


    data = folder_items_regex("02") 

    print "--- The dict ---------------" 
    pprint(data) 

    print "--- The items --------------" 
    pprint(sorted(data.keys())) 

    print "--- The files for item1 ---- " 
    pprint(sorted(data["item1"])) 
+0

большое спасибо за код! – Hellnar

+0

Добро пожаловать. Я только немного отредактировал его. Взгляни. Он может быть менее читаемым, но он может работать лучше (просто ощущение кишки). – exhuma

+0

* Очень важно *: В приведенном выше коде содержится ошибка. Если имя элемента содержало «_», код сломался бы со «слишком большим количеством значений для распаковки» (я думаю, это сообщение, которое оно даст). Я добавил параметр «maxsplit» для вызова «split». Это предотвратит ошибку. – exhuma

0

Предполагая, что имена элементов имеют фиксированный префикс длины и суффикс (т.е. 3 символа префикса, такие как «01_» и 4 символа суффикс «.xml»), вы могли бы решить первую часть задачи, как это:

names = set(name[3:-4] for name in os.listdir('01') if name.endswith('.xml')] 

это поможет вам уникальные имена элементов.

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

item_suffix = '_item2.xml' 
filtered = sorted(name for name in os.listdir('01') if name.endswith(item_suffix)) 
0

Не уверен, что именно то, что вы хотите сделать, но вот несколько советов, которые могут быть полезны


создания имен файлов («% 02d» означает площадку слева нулями)

foldernames = ["%02d"%i for i in range(1,13)]

filenames = ["%02d"%i for i in range(1,24)]


использование os.path.join для построения сложных путей вместо конкатенации

os.path.join(foldername,filename) 

os.path.существует для проверки, существует ли файл первого

if os.path.exists(newname): 
    print "file already exists" 

для листинга содержимого каталога, используйте Glob

from glob import glob 
xmlfiles = glob("*.xml") 

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

shutil.move(oldname,newname)


базовое имя, чтобы получить имя файла из полного пути

filename = os.path.basename(fullpath)