5

I want to test:

  1. to see whether or not ONE AND ONLY ONE shapefile (which will be based on a filename wildcard) exists in a directory.
  2. Add these shapefiles to a list
  3. Use this list variable as an input to merge_managment function.

I already know how to walk through directories and pick out those filenames but not how to do the above.

I was thinking something like:

rootDir = "\homePath"
featureinput1 = "path"
newOnlyShpList = []
for dirPath, dirNames, fileNames in os.walk(rootDir):
    for file in fileNames:
       if fnmatch.fnmatch(file, "*" + "2012" + "*" + ".shp")== True ##AND IF ONE SHAPEFILE EXISTS BY ITSELF IN DIRECTORY:##
          ##append to newOnlyShpList
          arcpy.Merge_managment([featureinput1, newOnlyShpList], "OutputHere")
       elif
          ##ignore if greater than one shapefile

All I know about is the arcpy .exists function but all that does is return a boolean on whether any shapefile exists. Maybe I need to check just for 1 .shp extension and it has nothing to do with arcpy?

1
  • you want to combine all the shapefiles which contain the word 2012 in one ?
    – nickves
    Commented Jul 22, 2012 at 18:43

3 Answers 3

7

Check the glob library:

import os
import glob
path = "c:\\my\\dir"

flist = glob.glob(os.path.join(path,"shapefile*"))  <- Notice the *

>>> flist 
["c:\\my\\dir\shapefile.prj","c:\\my\\dir\shapefile.shp",...]

If you want just the fname without the path attached:

 os.path.basename(flist[0]) 
 >>> shapefile.prj

if you want just the file name without the extension:

os.path.basename(flist[0]).split(".")[0]
>>> shapefile

Also if the list is empty, then the file doesn't exist:

if flist not:
    print "File not found"
    break #or os.exit(1)

Edit: Also to check for the only filename in path :

import os
import glob
path = "c:\\my\\dir"

flist = glob.glob(os.path.join(path,"shapefile*"))  <- Notice the *
mlist = []
for file in flist:
    if os.path.basename(file).split(".")[0] not in mlist:
        mlist.append(os.path.basename(file).split(".")[0])
if len(mlist)>1: #(More than filename)
    break

To check if only one shapefile in the dir:

 def file_check(path):
      """Returns true if in path there is only one basename"""
      import os
      mlist = [] 
      for file in os.listdir(path):
          if os.path.basename(file).split(".")[0] not in mlist:
                mlist.append(os.path.basename(file).split(".")[0]
   if len(mlist)>1:
            return True
    else:
            return False
6
  • What is the difference between glob and fnmatch that i was using? Also being new to python when you add [0] after split what is that referring to?
    – BDee
    Commented Jul 22, 2012 at 17:50
  • And i need to join dirPath and file since I am using os.walk in rootDir. Otherwise it doesnt have the filepath to merge once the shapefile in the directory by itself is found.
    – BDee
    Commented Jul 22, 2012 at 18:01
  • glob returns a list we can play with. fnmatch as far as i know returns a boolean T/F value. Split, splits the string using the designated character. eg "this.is.true".split(".") will produce this list : ['this', 'is', 'true']. To select an element from the list you just designate which one you want starting from 0. So .split(".")[0] just says : " split the string at dots, and give me back the first occurrence" . You can find more info here docs.python.org/release/1.5.1p1/tut/lists.html
    – nickves
    Commented Jul 22, 2012 at 18:15
  • It's easy to joir dirPath and File in a single path once you have a list with the file names and the path: eg: for x in [x+".shp" for x in mlist]:print os.path.join(path,x)
    – nickves
    Commented Jul 22, 2012 at 18:29
  • Thanks for explanation. Havent had any luck so far, but one other thing. You use the glob.glob in the variable flist, but I don't see where flist is associated with anything else in the code.
    – BDee
    Commented Jul 22, 2012 at 19:47
6

ArcGIS has a built in function to list all shapefiles in a folder:

import arcpy
from arcpy import env    

arcpy.env.workspace = 'E:/myFolder/'
fcs = arcpy.ListFeatureClasses("*.shp", "")

fcs is an array that stores the name of all of the shapefiles in the folder myFolder. For example, to print out all of the shapefiles in myFolder you can just do this:

for shp in fcs:    
    print shp

[just moving this from the comment] To test if the list of files contains only the file that you want in this folder, you could use the condition:

if 'myfile' in fcs and len(fcs)==1:
       print 'true'
3
  • Aware of this, but doesnt really help when you have to walk through a number of directories and pick out those shapfiles that are by themselves in a directory. And then throw them in a new list. I appreciate user528025 ideas, but it so different from what I began with that I am having a hard time grasping it and getting anything to work. I guess that is what I get for trying to do something above my python level.
    – BDee
    Commented Jul 22, 2012 at 21:27
  • 2
    you can still walk through all the folders as you are doing, and just use arcpy.ListFeatureClasses("*.shp", "") in each folder. To see if the filelist contains only that file you could use the condition if 'myfile' in fcs and len(fcs)==1:...
    – djq
    Commented Jul 22, 2012 at 21:57
  • Alright I will give it a try when I have arcpy module available to me. And probably get back to you for help later =D
    – BDee
    Commented Jul 22, 2012 at 22:15
-1

To answer this question nowadays (since ArcGIS 10.1 SP1) I would recommend the answer from @djq in conjunction with using arcpy.da.Walk to walk the folder structure:

Generate data names in a directory/database structure by walking the tree top-down or bottom-up. Each directory/workspace yields a tuple of three: directory path, directory names, and file names.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.