1

I am trying to transfer shapefiles by the number of shapefiles from one folder to another, But I want to keep the already existing files in the output folder. Is there any way? I am using the following script:

import arcpy
import os
from os import listdir
from os.path import isfile, join, basename
arcpy.env.overwriteOutput = True
arcpy.env.workspace =arcpy.GetParameterAsText(0)
outfolder = arcpy.GetParameterAsText(1)
shpNumber=int(arcpy.GetParameterAsText(2))
files = arcpy.ListFeatureClasses("*.shp", "")
if not os.path.exists(outfolder):
 os.makedirs(outfolder)
n=0
nf=[]
for f in files:
 n+=1
 if n<=shpNumber:
 nf.append(f)
 # copy the file
for ff in nf:
 outpath=os.path.join (outfolder,'{ff}.shp'.format(ff=ff))
 arcpy.CopyFeatures_management(ff, outpath)
 arcpy.Delete_management(ff)
Vince
20.5k16 gold badges49 silver badges65 bronze badges
asked Feb 7, 2022 at 14:54
2
  • 1
    I suggest to save with a different name and make old ones read-only if you happen to make a mistake with naming. By your code it looks like you definitely want to overwrite the existing files arcpy.env.overwriteOutput = True, avoid that if you don't like it. Commented Feb 7, 2022 at 15:30
  • Thank you very much for your response: I tried True Overwright or without it, the same result. The problem is that I deal with a large number of files that were created, about 13,000 files for each of the thirty years, and sometimes in order to reduce the slowness of the computer, I need a mass transfer of the processed files in order to continue processing the rest. . I am trying to automate data processing and therefore the option to create multiple folders does not allow software users to be completely comfortable with work. Commented Feb 7, 2022 at 16:51

1 Answer 1

3

You need to check if the file already exists using arcpy.Exists(output_path) and ignore the shapefile:

if arcpy.Exists(output_path):
 continue

Alternatively, you could also use os.path.exists(output_path). There are some other things I would like to point out:

  • In your example, ff would be a file name including extension. Assuming ff is lakes.shp, then '{ff}.shp'.format(ff=ff) would evaluate to lakes.shp.shp.
  • Use arcpy.env.overwriteOutput = False to make sure that files are never overwritten. An error would occur in case there is a bug in the script to prevent accidental overwritten files.
  • Consider using enumerate (as you see in my examples) instead of two loops

Here is an example using arcpy.Exists(output_path) along with the other suggested changes:

import arcpy
import os
arcpy.env.overwriteOutput = False
arcpy.env.workspace = arcpy.GetParameterAsText(0)
output_folder = arcpy.GetParameterAsText(1)
max_number = int(arcpy.GetParameterAsText(2))
if not os.path.exists(output_folder):
 os.makedirs(output_folder)
files = arcpy.ListFeatureClasses("*.shp")
for i, file in enumerate(files, 1):
 if i > max_number:
 break
 output_path = os.path.join(output_folder, file)
 if arcpy.Exists(output_path):
 continue
 arcpy.management.CopyFeatures(file, output_path)

Alternatively, you can also change the file name of the duplicate file:

import arcpy
import os
import time
arcpy.env.overwriteOutput = False
arcpy.env.workspace = arcpy.GetParameterAsText(0)
output_folder = arcpy.GetParameterAsText(1)
max_number = int(arcpy.GetParameterAsText(2))
if not os.path.exists(output_folder):
 os.makedirs(output_folder)
files = arcpy.ListFeatureClasses("*.shp")
for i, file in enumerate(files, 1):
 if i > max_number:
 break
 output_path = os.path.join(output_folder, file)
 if arcpy.Exists(output_path):
 # replace with a better suffix... this is just an example
 timestamp = int(time.time()) 
 output_path = output_path.replace(".shp", f"_{timestamp}.shp")
 arcpy.management.CopyFeatures(file, output_path)

Note: Your solution, and both of my examples, takes the first n files (equals to max_number) from the result list of arcpy.ListFeatureClasses("*.shp").

Unfortunately, the documentation does not specify the order of the list. From all we know this could be completely random.

You could use following code instead of files = arcpy.ListFeatureClasses("*.shp") to ensure that the file order is always the same:

unsorted_files = Path(arcpy.env.workspace).glob("*.shp")
# sorts unsorted_files list by modification time 
files = sorted(unsorted_files, key=os.path.getmtime)

However, files' elements are Path objects. You can access the file name with file.name (assuming file is a Path object). Here an example:

import arcpy
import os
import time
arcpy.env.overwriteOutput = False
arcpy.env.workspace = arcpy.GetParameterAsText(0)
output_folder = arcpy.GetParameterAsText(1)
max_number = int(arcpy.GetParameterAsText(2))
if not os.path.exists(output_folder):
 os.makedirs(output_folder)
unsorted_files = Path(arcpy.env.workspace).glob("*.shp")
# sorts unsorted_files list by modification time 
files = sorted(unsorted_files, key=os.path.getmtime)
for i, file in enumerate(files, 1):
 if i > max_number:
 break
 output_path = os.path.join(output_folder, file.name)
 
 if arcpy.Exists(output_path):
 continue
 arcpy.management.CopyFeatures(file.name, output_path)
answered Feb 7, 2022 at 20:48
2
  • Tank you very much it is helps me !!! Commented Feb 7, 2022 at 22:59
  • 1
    @YounesIdriss Please upvote and accept the answer by selecting the green check mark next to the answer if this answered your question. Commented Feb 8, 2022 at 2:03

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.