una texto recorrer manejo leer existe escanear directorios directorio crear copiar con comprobar carpeta archivos python python-3.x directory glob

texto - ¿Cómo mover y renombrar los documentos colocados en varias carpetas anidadas en una nueva carpeta única con python?



python crear carpeta si no existe (2)

¿Cómo funciona esto para ti?

import os import pathlib OLD_DIR = ''files'' NEW_DIR = ''new_dir'' p = pathlib.Path(OLD_DIR) for f in p.glob(''**/*.xml''): new_name = ''{}_{}''.format(f.parent.name, f.name) f.rename(os.path.join(NEW_DIR, new_name))

Si no tiene una versión moderna de Python (3.5+), también puede usar glob, os y shutil:

import os import glob import shutil for f in glob.glob(''files/**/*.xml''): new_name = ''{}_{}''.format(os.path.basename(os.path.dirname(f)), os.path.basename(f)) shutil.move(f, os.path.join(''new_dir'', new_name))

Tengo varios archivos en varias carpetas como esta:

dir ├── 0 │   ├── 103425.xml │   ├── 105340.xml │   ├── 109454.xml │ │── 1247 │   └── doc.xml ├── 14568 │   └── doc.xml ├── 1659 │   └── doc.xml ├── 10450 │   └── doc.xml ├── 10351 │   └── doc.xml

¿Cómo puedo extraer todos los documentos en una sola carpeta adjuntando el nombre de la carpeta para cada documento movido?

new_dir ├── 0_103425.xml ├── 0_105340.xml ├── 0_109454.xml ├── 1247_doc.xml ├── 14568_doc.xml ├── 1659_doc.xml ├── 10450_doc.xml ├── 10351_doc.xml

Intenté extraerlos con:

import os for path, subdirs, files in os.walk(''../dir/''): for name in files: print(os.path.join(path, name))

ACTUALIZAR

Además, traté de:

import os, shutil from glob import glob files = [] start_dir = os.getcwd() pattern = "*.xml" for dir,_,_ in os.walk(''../dir/''): files.extend(glob(os.path.join(dir,pattern))) for f in files: print(f) shutil.move(f, ''../dir/'')

Lo anterior me dio la ruta de cada archivo. Sin embargo, no entiendo cómo cambiar el nombre y moverlos:

--------------------------------------------------------------------------- Error Traceback (most recent call last) <ipython-input-50-229e4256f1f3> in <module>() 10 for f in files: 11 print(f) ---> 12 shutil.move(f, ''../dir/'') /usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/shutil.py in move(src, dst, copy_function) 540 real_dst = os.path.join(dst, _basename(src)) 541 if os.path.exists(real_dst): --> 542 raise Error("Destination path ''%s'' already exists" % real_dst) 543 try: 544 os.rename(src, real_dst) Error: Destination path ''../data/230948.xml'' already exists

El error anterior muestra por qué me gustaría cambiarle el nombre con su carpeta.


Esto es más fácil de hacer con el nuevo módulo pathlib Python 3 para operaciones de ruta, y luego shutil.move para mover los archivos a sus lugares correctos. A diferencia de os.rename , shutil.move funcionará como el comando mv y se comportará correctamente incluso para movimientos de sistemas de archivos cruzados.

Este código funcionará para rutas anidadas a cualquier nivel; cualquier / o / en las rutas se reemplazará con _ en el nombre de archivo de destino, por lo que dir/foo/bar/baz/xyzzy.xml se new_dir/foo_bar_baz_xyzzy.xml a new_dir/foo_bar_baz_xyzzy.xml .

from pathlib import Path from shutil import move src = Path(''dir'') dst = Path(''new_dir'') # create the target directory if it doesn''t exist if not dst.is_dir(): dst.mkdir() # go through each file for i in src.glob(''**/*''): # skip directories and alike if not i.is_file(): continue # calculate path relative to `src`, # this will make dir/foo/bar into foo/bar p = i.relative_to(src) # replace path separators with underscore, so foo/bar becomes foo_bar target_file_name = str(p).replace(''/'', ''_'').replace(''//', ''_'') # then do rename/move. shutil.move will always do the right thing # note that it *doesn''t* accept Path objects in Python 3.5, so we # use str(...) here. `dst` is a path object, and `target_file_name # is the name of the file to be placed there; we can use the / operator # instead of os.path.join. move(str(i), str(dst / target_file_name))