borrar - copiar archivos python
Escanee archivos recursivamente y elimine directorios vacíos en python (5)
Bueno, supongo que esto servirá, pero debo ejecutar os.walk ...
def get_files(src_dir):
# traverse root directory, and list directories as dirs and files as files
for root, dirs, files in os.walk(src_dir):
path = root.split(''/'')
for file in files:
process(os.path.join(root, file))
os.remove(os.path.join(root, file))
def del_dirs(src_dir):
for dirpath, _, _ in os.walk(src_dir, topdown=False): # Listing the files
if dirpath == src_dir:
break
try:
os.rmdir(dirpath)
except OSError as ex:
print(ex)
def main():
get_files(src_dir)
del_dirs(src_dir)
if __name__ == "__main__":
main()
Tengo la siguiente estructura:
Dir 1
|___Dir 2
|___file 1
|___file 2...
Dir 3
|___Dir 4
|___file 3...
Me gustaría poder encontrar cada archivo recursivamente, procesar el archivo a mi manera, una vez hecho, eliminar el archivo, pasar al siguiente. Luego, si el directorio está vacío, elimínelo también, trabajando hasta que no quede nada.
Simplemente no estoy seguro de cómo proceder.
Esto es lo que tengo:
for root, dirs, files in os.walk(dir):
path = root.split(''/'')
for file in files:
file = os.path.join(root, file)
process_file(file)
os.remove(file)
Lo cual está bien, pero me gustaría eliminar los subdires si solo están vacíos.
Me doy cuenta de que esta publicación es más antigua y que no tiene sentido agregar un ejemplo adicional, pero de un vistazo pensé que sería más fácil de entender para un principiante que algunos de los otros aquí porque no hay unión, solo importa un módulo, y proporciona buenos ejemplos de cómo usar algunas funciones incorporadas [open () y len ()] y el nuevo formato de cadenas de Python3 con str.format. También muestra cuán simple es poblar contenidos en un archivo en la función print (), usando file = filename.
Esta secuencia de comandos escaneará un directorio raíz con os.walk (), verificará la longitud de los directorios y archivos y realizará las condiciones en función de lo que encuentre. También incrementa un contador para determinar la cantidad de directorios usados y vacíos, y genera la información en un archivo. Escribí este ejemplo en Python 3.4 y funcionó para mis propósitos. Si alguien tiene ideas para mejorar la lógica, publique en los comentarios para que todos podamos aprender una nueva perspectiva para resolver el problema.
import os
#declare the root directory
root_dir = ''C://tempdir//directory//directory//'
#initialize the counters
empty_count = 0
used_count = 0
#Set the file to write to. ''x'' will indicate to create a new file and open it for writing
outfile = open(''C://tempdir//directories.txt'', ''x'')
for curdir, subdirs, files in os.walk(root_dir):
if len(subdirs) == 0 and len(files) == 0: #check for empty directories. len(files) == 0 may be overkill
empty_count += 1 #increment empty_count
print(''Empty directory: {}''.format(curdir), file = outfile) #add empty results to file
os.rmdir(curdir) #delete the directory
elif len(subdirs) > 0 and len(files) > 0: #check for used directories
used_count += 1 #increment used_count
print(''Used directory: {}''.format(curdir), file = outfile) #add used results to file
#add the counters to the file
print(''empty_count: {}/nused_count: {}''.format(empty_count, used_count), file = outfile)
outfile.close() #close the file
import os
#Top level of tree you wish to delete empty directories from.
currentDir = r''K:/AutoCAD Drafting Projects/USA/TX/Image Archive''
index = 0
for root, dirs, files in os.walk(currentDir):
for dir in dirs:
newDir = os.path.join(root, dir)
index += 1
print str(index) + " ---> " + newDir
try:
os.removedirs(newDir)
print "Directory empty! Deleting..."
print " "
except:
print "Directory not empty and will not be removed"
print " "
Agradable y simple. La clave es usar os.removedirs en una declaración try. Ya es recursivo
Aquí hay otra solución que creo que es eficiente. Por supuesto, la eficiencia puede mejorarse mediante el uso de os.scandir .
Primero, defino una función rec_rmdir
propósito general (rmdir recursivo) que explora el árbol de directorios recursivamente.
- La función procesa primero cada archivo y cada subdirectorio.
- Luego intenta eliminar el directorio actual.
- El indicador de conservar se usa para conservar el directorio raíz.
El algoritmo es una búsqueda clásica en profundidad .
import os
import stat
def rec_rmdir(root, callback, preserve=True):
for path in (os.path.join(root, p) for p in os.listdir(root)):
st = os.stat(path)
if stat.S_ISREG(st.st_mode):
callback(path)
elif stat.S_ISDIR(st.st_mode):
rec_rmdir(path, callback, preserve=False)
if not preserve:
try:
os.rmdir(root)
except IOError:
pass
Entonces, es fácil definir una función que procesa el archivo y lo elimina.
def process_file_and_remove(path):
# process the file
# ...
os.remove(path)
Uso clásico:
rec_rmdir("/path/to/root", process_file_and_remove)
Esto es solo para eliminar directorios vacíos y también extraer archivos individuales de directorios. Parece que solo responde una parte de la pregunta, lo siento.
Añadí un bucle al final para seguir intentándolo hasta que no pueda encontrar más. Hice que la función devuelva un conteo de directorios eliminados.
Mis errores de acceso denegado fueron solucionados por: shutil.rmtree falla en Windows con ''Acceso denegado''
import os
import shutil
def onerror(func, path, exc_info):
"""
Error handler for ``shutil.rmtree``.
If the error is due to an access error (read only file)
it attempts to add write permission and then retries.
If the error is for another reason it re-raises the error.
Usage : ``shutil.rmtree(path, ignore_errors=False, onerror=onerror)``
"""
import stat
if not os.access(path, os.W_OK):
# Is the error an access error ?
os.chmod(path, stat.S_IWUSR)
func(path)
else:
raise
def get_empty_dirs(path):
# count of removed directories
count = 0
# traverse root directory, and list directories as dirs and files as files
for root, dirs, files in os.walk(path):
try:
# if a directory is empty there will be no sub-directories or files
if len(dirs) is 0 and len(files) is 0:
print u"deleting " + root
# os.rmdir(root)
shutil.rmtree(root, ignore_errors=False, onerror=onerror)
count += 1
# if a directory has one file lets pull it out.
elif len(dirs) is 0 and len(files) is 1:
print u"moving " + os.path.join(root, files[0]) + u" to " + os.path.dirname(root)
shutil.move(os.path.join(root, files[0]), os.path.dirname(root))
print u"deleting " + root
# os.rmdir(root)
shutil.rmtree(root, ignore_errors=False, onerror=onerror)
count += 1
except WindowsError, e:
# I''m getting access denied errors when removing directory.
print e
except shutil.Error, e:
# Path your moving to already exists
print e
return count
def get_all_empty_dirs(path):
# loop till break
total_count = 0
while True:
# count of removed directories
count = get_empty_dirs(path)
total_count += count
# if no removed directories you are done.
if count >= 1:
print u"retrying till count is 0, currently count is: %d" % count
else:
break
print u"Total directories removed: %d" % total_count
return total_count
count = get_all_empty_dirs(os.getcwdu()) # current directory
count += get_all_empty_dirs(u"o://downloads//") # other directory
print u"Total of all directories removed: %d" % count