This may seem trivial, but I can seem to track the error and I am very very new to Python, though not to programming. From reading around on the internet for a bit, I think my problem is that .dat ENVI image file isn't being read as a "describe object". But how do I get it to be read as such? I probably need it to read the header info too, any solutions?
Here is my code:
import arcpy #make sure you run the python associated with ArcGIS
import os
filepath = 'filepath'
filename = 'filename'
band_names = range(1,225)
# Path creation
in_folder = filepath + os.sep + 'ENVI'
out_folder = filepath + os.sep + 'GeoTIFF' # preferably an empty folder
# input multiband raster
in_ENVI = in_folder + filename '.dat'
in_raster = raster(in_ENVI)
index = 0
# get raster information specific to each band
desc = arcpy.Describe(in_raster)
################### THIS IS WHERE I GET THE ERROR ##################
Runtime error
Traceback (most recent call last):
File "<string>", line 23, in <module>
NameError: name 'raster' is not defined
################### SCRIPT TERMINATED ##############################
for band in desc.children:
print band
bandName = band.name
band_path = os.path.join(in_raster, bandName)
dest_path = os.path.join(out_folder, filename '_' + band_names(index) + '.tif')
arcpy.CopyRaster_management(band_path, dest_path, "", "", "", "NONE", "NONE", "")
index = index + 1
Ok so I actually figured it out myself. Here is the code I used. The error was actually not in arcpy.Describe() but in arcpy.CopyRaster_management because I didn't convert band_name[index] to a string.
dest_path = os.path.join(out_folder, filename + str(band_names[index]) + '.tif')
Related
I'm attempting to rename a file and am successful in doing so until the last line below. Using os.rename, no matter what I've tried (f strings for example) I just can't get it to work. I'm getting quadruple and double slashes in the output. I'm sure it's a simple resolution. Any help would be greatly appreciated.
import os
from os import path
import shutil
from datetime import date
WDPath = r'\\xxx\yyy\gis\SAP_IMPORT_SQLARCGIS'
ARCHIVE_PATH = r'\\xxx\yyy\gis\SAP_IMPORT_SQLARCGIS\ARCHIVE\GISDEVICES'
IMPORT_FILE_NAME = r'\GISDEVICES.txt'
IMPORT_FILE = os.path.join(f'{WDPath}{IMPORT_FILE_NAME}')
print(IMPORT_FILE, '\n')
# split the file into filename and extension
filename, extension = os.path.splitext(IMPORT_FILE_NAME)
print(filename, extension, '\n')
# Get the create time of the file
create_time = os.path.getctime(IMPORT_FILE)
print(create_time, '\n')
# get the readable timestamp format
## format_time = datetime.datetime.fromtimestamp(create_time)
format_time = date.fromtimestamp(create_time)
print(format_time, '\n')
# convert time into string
format_time_string = format_time.strftime("-%Y-%m-%d")
print(format_time_string, '\n')
# Contruct the new name of the file
newfile = filename + format_time_string + extension
print(newfile, '\n')
# rename the file
os.rename(IMPORT_FILE, newfile)
print(IMPORT_FILE)
RESULT >>
\\nasgriver\SAP_Share\gis\SAP_IMPORT_SQLARCGIS\GISDEVICES.txt
\GISDEVICES .txt
1614332702.039849
2021-02-26
-2021-02-26
\GISDEVICES-2021-02-26.txt
Traceback (most recent call last):
File "\\xxx\yyy\gis\SAP_IMPORT_SQLARCGIS\MOVERENAMEFILE.py", line 42, in <module>
os.rename(IMPORT_FILE, newfile)
OSError: [WinError 17] The system cannot move the file to a different disk drive: '\\\\xxx\\yyy\\gis\\SAP_IMPORT_SQLARCGIS\\GISDEVICES.txt' -> '\\GISDEVICES-2021-02-26.txt'
Using the path submodule of os can come with some annoyance, you can try with pathlib instead:
import os
from pathlib import Path
import shutil
from datetime import date
WDPath = Path(r"\\xxx\yyy\gis\SAP_IMPORT_SQLARCGIS")
ARCHIVE_PATH = Path(r"\\xxx\yyy\gis\SAP_IMPORT_SQLARCGIS\ARCHIVE)\GISDEVICES")
IMPORT_FILE_NAME = "GISDEVICES.txt"
IMPORT_FILE = WDPath / IMPORT_FILE_NAME
print(IMPORT_FILE, '\n')
# split the file into filename and extension
filename, extension = os.path.splitext(IMPORT_FILE_NAME)
print(filename, extension, '\n')
# Get the create time of the file
create_time = os.path.getctime(IMPORT_FILE)
print(create_time, '\n')
# get the readable timestamp format
## format_time = datetime.datetime.fromtimestamp(create_time)
format_time = date.fromtimestamp(create_time)
print(format_time, '\n')
# convert time into string
format_time_string = format_time.strftime("-%Y-%m-%d")
print(format_time_string, '\n')
# Contruct the new name of the file
newfile = filename + format_time_string + extension
print(newfile, '\n')
# rename the file
IMPORT_FILE.rename(IMPORT_FILE / newfile)
print(IMPORT_FILE)
Situation:
I'm attempting to rename XLS files in a directory using a specific cell value from each file (i.e. Cell A4 contains "Name1", use A4 to create Name1.xls). There's a script I found that will work for my purposes.
Problem I'm trying to solve:
Every cell I'm attempting to use as the filename has spaces and special characters. Ideally, I'd like to remove all the special characters and white spaces, and use that as the value to name each file. I'm not very familiar with regex so I'm not sure if I should be modifying the fileNameCheck = re.compile('[^\w,\s-]') part of the code, or modify first if not block...
See below code:
# Import required modules
import openpyxl
import os
import re
import shutil
# File path
filePath = 'C:\\Users\name\Documents\Python\folder'
# Cell containing new file name
cellForFileName = 'A3'
# Check to see if the file path exists
if os.path.exists(filePath):
# Change the current working directory
os.chdir(filePath)
# Check if there are any files in the chosen directory
if len(os.listdir(filePath)) == 0:
print('There are no files to rename')
else:
# Renamed file count
filesRenamed = 0
# Process the files at the path
for filename in os.listdir(filePath):
# Check if the file is an Excel file, excluding temp files
if filename.endswith('.xls.xlsx') and not filename.startswith('~'):
try:
# Open the file and find the first sheet
workbook = openpyxl.load_workbook(filename)
worksheet = workbook.worksheets[0]
# Check if there is a value in the cell for the new file name
if worksheet[cellForFileName].value is not None:
# Check to see if the cell value is valid for a file name
fileNameCheck = re.compile('[^\w,\s-]')
if not fileNameCheck.search(worksheet[cellForFileName].value):
# Construct the new file name
newFileName = worksheet[cellForFileName].value + '.xlsx'
# Close the workbook
workbook.close()
# Rename the file
shutil.move(filename, newFileName)
# Output confirmation message
print('The file "' + filename + '" has been renamed to "'
+ newFileName + '".')
# Increment the count
filesRenamed += 1
else:
# Display a message saying the file could not be renamed
print('The file "' + filename + '" could not be renamed.')
# Close the workbook
workbook.close()
else:
# Display a message saying the file could not be renamed
print('The file "' + filename + '" could not be renamed.')
# Close the workbook
workbook.close()
except PermissionError as e:
# Display a message saying the file could not be renamed
print('The file "' + filename + '" could not be renamed.')
# Display a message regarding the number of files renamed
if filesRenamed == 1:
print(str(filesRenamed) + ' file has been renamed.')
else:
print(str(filesRenamed) + ' files have been renamed.')
else:
# Display a message stating that the file path does not exist
print('File path does not exist.')
Thanks in advance for any help, advice, tips you can provide!
I think filename.endswith('.xls.xlsx') would not work the way is expected, following the documentation of str.endswith you may use a tuple (.endswith(('.xls','.xlsx')). ) to match both .xls and .xlsx, furthermore, if you are working with both types of files is better to know the original extension and match that suffix during rename operation since they are interpreted in distinct ways.
... information [...] stored is vastly different for both XLS and XLSX formats. XLS is based on BIFF (Binary Interchange File Format) and as such, the information is directly stored to a binary format. On the other hand, XLSX is based on the Office Open XML format, a file format that was derived from XML... [1]
You may use _, extension = os.path.splitext(filename) to get only the extension part to use later on the rename operation.
To remove special characters and spaces, you may use re.sub("[^a-zA-Z0-9]", "", nameCell). If the string after the : is allowed to contain only special characters and spaces, make sure to test for an empty string before writing the file name.
...
...
# Process the files at the path
for filename in os.listdir(filePath):
# get extension to use later on file rename
_, extension = os.path.splitext(filename)
if filename.endswith(('.xls','.xlsx')) and not filename.startswith('~'):
try:
workbook = openpyxl.load_workbook(filename)
worksheet = workbook.worksheets[0]
# get the text after the ":"
nameCell = re.search(":(.+)", worksheet[cellForFileName].value).group(1)
# or use str.split(":")[1], make sure the range exists
workbook.close()
if nameCell is not None:
# remove special characters and spaces
clearName = re.sub("[^a-zA-Z0-9]", "", nameCell)
newFileName = clearName + extension
shutil.move(filename, newFileName)
print('The file "' + filename + '" has been renamed to "'
+ newFileName + '".')
filesRenamed += 1
else:
print('The file "' + filename + '" could not be renamed.')
except PermissionError as e:
...
...
...
I have a few hundred .mp4 files in a directory. When originally created their names were set as "ExampleEventName - Day 1", "ExampleEventName - Day 2" etc. thus they are not in chronological order.
I need a script to modify each of their names by taking the last 5 characters in the corresponding string and add it to the front of the name so that File Explorer will arrange them properly.
I tried using the os module .listdir() and .rename() functions, inside a for loop. Depending on my input I get either a FileNotFoundError or a TypeError:List object is not callable.
import os
os.chdir("E:\\New folder(3)\\New folder\\New folder")
for i in os.listdir("E:\\New folder(3)\\New folder\\New folder"):
os.rename(i, i[:5] +i)
Traceback (most recent call last):
File "C:/Python Projects/Alex_I/venv/Alex_OS.py", line 15, in <module>
os.rename(path + i, path + i[:6] +i)
FileNotFoundError: [WinError 2] The system cannot find the file specified:
import os, shutil
file_list = os.listdir("E:\\New folder(3)\\New folder\\New folder")
for file_name in file_list("E:\\New folder(3)\\New folder\\New folder"):
dst = "!#" + " " + str(file_name) #!# meant as an experiment
src = "E:\\New folder(3)\\New folder\\New folder" + file_name
dst = "E:\\New folder(3)\\New folder\\New folder" + file_name
os.rename(src, dst)
file_name +=1
Traceback (most recent call last):
File "C:/Python Projects/Alex_I/venv/Alex_OS.py", line 14, in <module>
for file_name in file_list("E:\\New folder(3)\\New folder\\New folder"):
TypeError: 'list' object is not callable
Some other approach:
Not based on based length ( 5 for subname )
import glob
import os
# For testing i created 99 files -> asume last 5 chars but this is wrong if you have more files
# for i in range(1, 99):
# with open("mymusic/ExampleEventName - Day {}.mp4".format(i), "w+") as f:
# f.flush()
# acording to this i will split the name at - "- Day X"
files = sorted(glob.glob("mymusic/*"))
for mp4 in files:
# split path from file and return head ( path ), tail ( filename )
head, tail = os.path.split(mp4)
basename, ext = os.path.splitext(tail)
print(head, tail, basename)
num = [int(s) for s in basename.split() if s.isdigit()][0] #get the number extracted
newfile = "{}\\{}{}{}".format(head, num, basename.rsplit("-")[0][:-1], ext) # remove - day x and build filename
print(newfile)
os.rename(mp4, newfile)
You're having multiple problems:
You're trying to increment a value that should not be incremented. Also you've created the list file_list, and thus it should not take any arguments anymore.
When using the syntax:
for x in y:
you do not have to increment the value. It will simply iterate through the list until there is no more left.
Therefore you simply have to leave out the incrementation and iterate through the list file_list.
import os, shutil
file_list = os.listdir("E:\\New folder(3)\\New folder\\New folder")
for file_name in file_list: #removed the argument, the as file_list is a list and thus not callable.
dst = "!#" + " " + str(file_name) #!# meant as an experiment
src = "E:\\New folder(3)\\New folder\\New folder" + file_name
dst = "E:\\New folder(3)\\New folder\\New folder" + file_name
os.rename(src, dst)
#file_name +=1 removed this line
Now your solution should work.
I'm trying to write a Python script that renames all duplicate file names recursively (i.e. inside all directories)
I already searched the web and Stack Overflow but I couldn't find any answer...
Here's my code:
#!/usr/bin/env python3.6
import os
import glob
path = os.getcwd()
file_list = []
duplicates={}
# remove filename duplicates
for file_path in glob.glob(path + "/**/*.c", recursive=True):
file = file_path.rsplit('/', 1)[1]
if file not in file_list:
file_list.append(file)
else:
if file in duplicates.keys():
duplicates[file] += 1
lista = []
lista.append(file_path)
os.rename(file_path, file_path.rsplit('/', 1)[:-1] + '/' + str(duplicates[file]) + file)
else:
duplicates[file] = 1
os.rename(file_path, file_path.rsplit('/', 1)[:-1] + '/' + str(duplicates[file]) + file)
And this is the error I'm getting:
Traceback (most recent call last):
File "/home/andre/Development/scripts/removeDuplicates.py", line 22, in <module>
os.rename(file_path, file_path.rsplit('/', 1)[:-1] + '/' + str(duplicates[file]) + file)
TypeError: can only concatenate list (not "str") to list
I know why I'm getting this error, but my question is: Is there a more clever way to do this? I'd also like to rename all duplicate directory names, but I still didn't figure it out...
I am trying to write a python script to process image files into shapefiles and then to buffer these files with a 5 meter buffer. I first made the script in model builder in arcmap but I am trying to run it for multiple image files, all beginning with the letters LG. I keep getting the error 00865, which states that the input raster (image file) does not exist!! I have checked the folder a million times and it definitely does exist! Here is my code:
# Import system modules
import sys, string, os, arcgisscripting
# Create the Geoprocessor object
gp = arcgisscripting.create()
# Load required toolboxes...
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Conversion Tools.tbx")
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Analysis Tools.tbx")
# Script arguments...
folder = "D:\\J04-0083\\IMAGEFILES"
for root, dirs, filenames in os.walk(folder): # returms root, dirs, and files
for filename in filenames:
filename_split = os.path.splitext(filename) # filename and extensionname (extension in [1])
filename_zero = filename_split[0]
try:
first_2_letters = filename_zero[0] + filename_zero[1]
except:
first_2_letters = "XX"
if first_2_letters == "LG":
Output_polygon_features = "D:\\J04-0083\\ShapeFiles.gdb\\" + "SH_" + filename + ".shp"
# Process: Raster to Polygon...
InRaster = filename_zero + ".png"
gp.RasterToPolygon_conversion(InRaster, Output_polygon_features, "SIMPLIFY", "VALUE") # FILL IN THE CORRECT VALUES!
Distance__value_or_field_ = "5 Meters"
Raster_Buffer_shp = "D:\\J04-0083\\ShapeFiles.gdb\\" + "SB_" + filename + ".shp"
# Process: Buffer...
gp.Buffer_analysis(Output_polygon_features, Raster_Buffer_shp, Distance__value_or_field_, "FULL", "ROUND", "NONE", "")
Does anyone have any idea why it doesn't work? thank you!
I don't know where you're running the script from, but when you call gp.RasterToPolygon_conversion, you're only giving it the file name, not the full path. If the file's not in the working directory, it won't find it. Try replacing the line:
InRaster = filename_zero + ".png"
With:
InRaster = os.path.join(root, filename_zero + ".png")