2012-01-31 10 views
1

使用されているファイル名が完全なファイル名の一部にすぎないディレクトリでファイルを検索しようとしています。"if .... in .."文にワイルドカードを使用する

ので

check_meta=os.listdir(currentPath) 

ので、時々使用するXMLがUrbanlevy_bdy_trc.shp.xmlであり、他でそれがUrbanlevy_bdy_trc.xmlである私は

existingXML=FileNm[:FileNm.find('.')] 
if existingXML+"*"+'.xml' in check_meta: # this is where the issue is 
    print "exists" 

にしたい

['ANZMeta.xsl', 'Benefited_Areas', 'divisons', 'emergency', 'Error_LOG.txt', 'hex.dbf', 'hex.shp', 'hex.shp_BaseMetadata.xml', 'hex.shx', 'Maintenance_Areas', 'Rates.mxd', 'Regulated_Parking', 'schema.ini', 'Service_Areas', 'Shortcut to Local_Govt.lnk', 'TAB', 'TRC.rar', 'trc_boundary.dbf', 'trc_boundary.kml', 'trc_boundary.prj', 'trc_boundary.sbn', 'trc_boundary.sbx', 'trc_boundary.shp', 'trc_boundary.shp.ATGIS29.1772.3444.sr.lock', 'trc_boundary.shp.ATGIS30.2668.2356.sr.lock', 'trc_boundary.shp.xml', 'trc_boundary.shx', 'trc_boundary_Metadata.xml.auto', 'trc_boundary_Polygon.dbf', 'trc_boundary_Polygon.prj', 'trc_boundary_Polygon.sbn', 'trc_boundary_Polygon.sbx', 'trc_boundary_Polygon.shp', 'trc_boundary_Polygon.shp.ATGIS29.1772.3444.sr.lock', 'trc_boundary_Polygon.shx', 'trc_boundary_polygon.xml', 'Urbanlevy_bdy_region.dbf', 'Urbanlevy_bdy_region.prj', 'Urbanlevy_bdy_region.shp', 'Urbanlevy_bdy_region.shp.xml', 'Urbanlevy_bdy_region.shx', 'Urbanlevy_bdy_trc.dbf', 'Urbanlevy_bdy_trc. prj', 'Urbanlevy_bdy_trc.sbn', 'Urbanlevy_bdy_trc.sbx', 'Urbanlevy_bdy_trc.shp', 'Urbanlevy_bdy_trc.shp.xml', 'Urbanlevy_bdy_trc.shx']

を与えます(いずれか存在するもの - 注:複数のファイルエクステンションが存在するため、 ".shp.xml"にOR機能を使用するだけではありませんl ikeタブ、ecwなど)を作成します。また、関連するxmlファイルはUrbanlevy_bdy_trc_Metadata.shp.xmlと呼ばれることもあります。コアファイル名 "Urbanlevy_bdy_trc"(拡張子.xml)を検索するためのキーです。

どうすれば指定できますか?

searchtext = "sometext" 
matching = [ f for f in os.listdir(currentPath) if f.startswith(searchtext) and ".xml" in f] 

を使用すると、別のextentionsをチェックしたい場合は、それらを一覧表示することができます。この目的は、Search and replace multiple lines in xml/text files using python

FULL CODEに

import os, xml, arcpy, shutil, datetime 
from xml.etree import ElementTree as et 

path=os.getcwd() 
RootDirectory=path 
arcpy.env.workspace = path 
Count=0 

Generated_XMLs=RootDirectory+'\GeneratedXML_LOG.txt' 
f = open(Generated_XMLs, 'a') 
f.write("Log of Metadata Creation Process - Update: "+str(datetime.datetime.now())+"\n") 
f.close() 

for root, dirs, files in os.walk(RootDirectory, topdown=False): 
    #print root, dirs 
    for directory in dirs: 
     currentPath=os.path.join(root,directory) 
     os.chdir(currentPath) 
     arcpy.env.workspace = currentPath 
     print currentPath 
#def Create_xml(currentPath): 

     FileList = arcpy.ListFeatureClasses() 
     zone="_Zone" 

     for File in FileList: 
      Count+=1 
      FileDesc_obj = arcpy.Describe(File) 
      FileNm=FileDesc_obj.file 
      print FileNm 

      check_meta=os.listdir(currentPath) 
      existingXML=FileNm[:FileNm.find('.')] 
      print "XML: "+existingXML 
      print check_meta 
      #if existingXML+'.xml' in check_meta: 
      if any(f.startswith(existingXML) and f.endswith('.xml') for f in check_meta): 
       print "exists" 
       newMetaFile=FileNm+"_2012Metadata.xml" 
       shutil.copy2(FileNm+'.xml', newMetaFile) 
      else: 
       print "Does not exist" 
       newMetaFile=FileNm+"_BaseMetadata.xml" 
       shutil.copy2('L:\Data_Admin\QA\Metadata_python_toolset\Master_Metadata.xml', newMetaFile) 
      tree=et.parse(newMetaFile) 

      print "Processing: "+str(File) 

      for node in tree.findall('.//title'): 
       node.text = str(FileNm) 
      for node in tree.findall('.//northbc'): 
       node.text = str(FileDesc_obj.extent.YMax) 
      for node in tree.findall('.//southbc'): 
       node.text = str(FileDesc_obj.extent.YMin) 
      for node in tree.findall('.//westbc'): 
       node.text = str(FileDesc_obj.extent.XMin) 
      for node in tree.findall('.//eastbc'): 
       node.text = str(FileDesc_obj.extent.XMax)   
      for node in tree.findall('.//native/nondig/formname'): 
       node.text = str(os.getcwd()+"\\"+File) 
      for node in tree.findall('.//native/digform/formname'): 
       node.text = str(FileDesc_obj.featureType) 
      for node in tree.findall('.//avlform/nondig/formname'): 
       node.text = str(FileDesc_obj.extension) 
      for node in tree.findall('.//avlform/digform/formname'): 
       node.text = str(float(os.path.getsize(File))/int(1024))+" KB" 
      for node in tree.findall('.//theme'): 
       node.text = str(FileDesc_obj.spatialReference.name +" ; EPSG: "+str(FileDesc_obj.spatialReference.factoryCode)) 
      print node.text 
      projection_info=[] 
      Zone=FileDesc_obj.spatialReference.name 

      if "GCS" in str(FileDesc_obj.spatialReference.name): 
       projection_info=[FileDesc_obj.spatialReference.GCSName, FileDesc_obj.spatialReference.angularUnitName, FileDesc_obj.spatialReference.datumName, FileDesc_obj.spatialReference.spheroidName] 
       print "Geographic Coordinate system" 
      else: 
       projection_info=[FileDesc_obj.spatialReference.datumName, FileDesc_obj.spatialReference.spheroidName, FileDesc_obj.spatialReference.angularUnitName, Zone[Zone.rfind(zone)-3:]] 
       print "Projected Coordinate system" 
      x=0 
      for node in tree.findall('.//spdom'): 
       for node2 in node.findall('.//keyword'): 
        print node2.text 
        node2.text = str(projection_info[x]) 
        print node2.text 
        x=x+1 


      tree.write(newMetaFile) 

      f = open(Generated_XMLs, 'a') 
      f.write(str(Count)+": "+File+"; "+newMetaFile+"; "+currentPath+"\n") 
      f.close() 



    #  Create_xml(currentPath) 

RESULT

+2

あなたがチェックアウトする必要があります'glob'モジュールです。また、 'os.path.splitext()'を使用して拡張子 –

+0

@gnibblerを取得しないと、これを回答に書くべきです。元のアプローチを働かせるよりも、このアプローチをとる方がはるかに良いでしょう。 –

答えて

0

は、以下のことを試してみてください。

if any(f.startswith(existingXML) and f.endswith('.xml') for f in check_meta): 
    print "exists" 

any()組み込み関数は、引数として反復可能を取り、要素のいずれかに該当する場合はtrueを返します。私たちが渡す引数は、リストcheck_metaの各ファイルfの値がf.startswith(existingXML) and f.endswith('.xml')になるジェネレータ式です。

正規表現ソリューションは、このようになります:

regex = re.compile(re.escape(existingXML) + '.*\.xml$') 
if any(regex.match(f) for f in check_meta): 
    print "exists" 

あなたは、エントリが実際に一致するかを知る必要がある場合は、代わりにforループを使用します。

for f in check_meta: 
    if f.startswith(existingXML) and f.endswith('.xml'): 
     print "exists, file name:", f 
+0

ありがとう...私はIOErrorを取得する任意のソリューション:[Errno 2]そのようなファイルやディレクトリはありません:u'Asc_Sewer_Catchments.xml '>>> existingXML u'Asc_Sewer_Catchments' ---存在するファイルはAsc_Sewer_Catchments.shp.xmlだから – GeorgeC

+0

@GeorgeC - これは奇妙なことですが、IOErrorを発生させるものはありません。エラーの原因となっているコードと完全な例外テキストを表示するために質問を編集できますか? –

+0

問題はあなたのコードではなく、次の行がどのようにXMLが呼び出されるかをどのように扱うかで問題になります。私はそれを把握しようとしています...見つけたxmlファイルの名前を吐き出すためにあなたの 'もしあれば'の声明を得ることができますか? – GeorgeC

1

理由だけで使用していないと述べていますでる。

exts = (".xml", ".tab", ".shp") 
matching = [ f for f in os.listdir(currentPath) if f.startswith(searchtext) and os.path.splitext(f)[-1] in exts] 

もちろん、同じことをするための正規表現を理解することもできます。

0
import fnmatch, posixpath 

existingXML = posixpath.splitext(FileNm)[-1] 
matchingFiles = fnmatch.filter(check_meta, existingXML + "*" + ".xml") 

if not matchingFiles: 
    raise IOError("no matching XML files") 
elif len(matchingFiles) > 1: 
    print "more than one matching file, using first" 
    matchingFile = matchingFiles[0] 
else: # only one was found, just use it 
    matchingFile = matchingFiles[0]