2015-02-14 2 views
0

У меня есть каталог с xml-файлами, связанный с зашифрованными файлами P7M, что означает, что для каждого name.xml существует имя.P7M. Но есть некоторые исключения (файл P7M отсутствует), и моя цель - обнаружить их с помощью python.Извлечение «неподписанных файлов» из каталога

Я думаю, этот код .. Вы можете помочь с элегантным кодом?

import glob 

# functions to eleminate extension name 
def is_xml(x): 
    a = re.search(r"(\s)(.xml)",x) 
    if a : 
    return a.group(0) 
    else: 
    return False 


def is_P7M(x): 
    a = re.search(r"(\s)(.P7M)", x) 
    if a : 
    return a.group(0) 
    else: 
    return False 

# putting xml files and P7M files in two sets 
setA = set (glob.glob('directory/*.xml')) 
setB = set (glob.glob('directory/*.P7M')) 


#eliminating extention names 
for elt in setA: 
    elt= is_xml(elt) 

for elt in setB: 
    elt= is_P7M(elt) 


#difference between two sets. setB is always a larger set 
print "unsigned files are:", setB.difference(setA) 

ответ

1

Более простой способ заключается в шарик для .xml файлов, а затем проверить с помощью os.path.exists для .P7M файла:

import os, glob 

for xmlfile in glob.glob('*.xml'): 
    if not os.path.exists(xmlfile.rsplit(".", 1)[0] + ".P7M"): 
     print xmlfile, "is unsigned" 

Этот код:

  1. Использует glob.glob, чтобы получить все файлы XML.
  2. Использует str.rsplit, чтобы разбить имя файла на имя и расширение (например, "name.xml" до ("name", ".xml")). Второй аргумент останавливает str.rsplit, разделяющий более одного раза.
  3. Принимает имя файла и добавляет расширение .P7M.
  4. Использует os.path.exists, чтобы увидеть, есть ли файл ключей. Если is is нет, xmlfile не имеет знака, поэтому распечатайте его.

Если вам нужно их в списке, вы можете сделать:

unsigned = [xmlfile for xmlfile in glob.glob('*.xml') if not os.path.exists(xmlfile.rsplit(".", 1)[0] + ".P7M")] 

или набор:

unsigned = {xmlfile for xmlfile in glob.glob('*.xml') if not os.path.exists(xmlfile.rsplit(".", 1)[0] + ".P7M")} 
1

получить все XML, в Словаре удаления расширения и используя имя в качестве ключа и установите значение ложь изначально, если мы найдем соответствующий P7M установленное значение в True, наконец, печатать все ключи с ложным значением.

xmls = glob.glob('directory/*.xml') 
p7ms = glob.glob('directory/*.P7M') 
# use xml file names as keys by removing the extension 
d = {k[rsplit(k,1)[0]]:False for k in xmls} 

# go over every .P7M again removing extension 
# setting value to True for every match 
for k in p7ms: 
    k[rsplit(k,1)[0]] = True 

# any values that are False means there is no .P7M match for the xml file 
for k,v in d.items(): 
    if not v: 
     print(k) 

Или создать набор каждого и найти разницу:

xmls = {x.rsplit(".",1)[0] for x in in glob.glob('directory/*.xml')} 
pm7s = {x.rsplit(".",1)[0] for x in glob.glob('directory/*.P7M')} 

print(xmls - pm7s) 
+0

вы можете объяснить с некоторыми комментариями пожалуйста? –

+0

@matsjoyce, да опечатка, спасибо –

1

перебрать glob раз и заполнить Dict имен файлов по расширению. Наконец, вычислите разницу между наборами «xml» и «P7M».

import os, glob, collections 

fnames = collections.defaultdict(set) 

for fname in glob.glob('*'): 
    f, e = os.path.splitext(fname) 
    fnames[e].add(f) 

print fnames['.xml'] - fnames['.P7M'] 

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

1

Мое решение будет:

import glob 
import os 

get_name = lambda fname: os.path.splitext(fname)[0] 
xml_names = {get_name(fname) for fname in glob.glob('directory/*.xml')} 
p7m_names = {get_name(fname) for fname in glob.glob('directory/*.p7m')} 
unsigned = [xml_name + ".xml" for xml_name in \ 
    xml_names.difference(p7m_names)] 

print unsigned 
Смежные вопросы