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)
1 Answer 1
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. Assumingff
islakes.shp
, then'{ff}.shp'.format(ff=ff)
would evaluate tolakes.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)
-
Tank you very much it is helps me !!!Younes Idriss– Younes Idriss2022年02月07日 22:59:03 +00:00Commented 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.2022年02月08日 02:03:31 +00:00Commented Feb 8, 2022 at 2:03
arcpy.env.overwriteOutput = True
, avoid that if you don't like it.