¿Cómo cambiar el nombre de los archivos en diferentes carpetas (pero todas las carpetas están en una carpeta) (sin considerar cuáles son sus nombres) a la base hexadecimal 16, de forma recursiva?
Entonces, cuando va a la siguiente carpeta, recuerda cuál fue el nombre anterior que hizo y continúa desde allí.
Por ejemplo (diferente a la captura de pantalla):
Carpeta1: 1.jpg, 1_A.jpg, ... 10th_blah.jpg
Carpeta2: 1.jpg , ..., 2000th_text1.jpg
se convertirá en ->
CarpetaTodoJunto: 1.jpg, 2.jpg, ..., A.jpg, B.jpg , ..., 7D0.jpg
La solución podría estar en javascript, bash, python o cualquier otro lenguaje de script que pueda ejecutar fácilmente en macOS.
Mi código:
const fs = require('fs') const path = require('path'); const dir = path.resolve(__dirname, 'ImagesSuperTemp'); let i = 0 function renameFilesRecursive(dir, from, to) { fs.readdirSync(dir).forEach(it => { const itsPath = path.resolve(dir, it); const itsStat = fs.statSync(itsPath); if (itsPath.search(from) > -1) { console.log(`${i} : rename ${from} to ${to}`); fs.renameSync(itsPath, itsPath.replace(from, to)) i = i + 1 } if (itsStat.isDirectory()) { renameFilesRecursive(itsPath.replace(from, to), from, to) } }) } renameFilesRecursive(dir, /\*.jpg$/, `${i.toString(16)}.jpg`);¡Pero no hace nada!
(le arroja un error si desea cambiar el nombre de un archivo que ya existe, por ejemplo, está procesando la imagen 5.jpg mientras su contador está en 3, pero 3.jpg ya existe; podría evitarlo con una cláusula de except de try , pero luego lo hace no tiene imágenes siempre incrementadas en 1, no estoy seguro de lo que necesita):
import os counter = 1 for r, d, f in os.walk(r"Images"): # can also put a full path here for name in f: # first argument here is full path to the image # second argument is the path + the hex number of the counter + the extension of the file os.rename(r + os.sep + name, r + os.sep + hex(counter).lstrip("0x") + os.path.splitext(name)[-1]) counter += 1Documenté aún más el código, agregué un mensaje de estado y noté que desea nombres de archivos hexadecimales en mayúsculas:
import os counter = 1 for r, d, f in os.walk(r"Images"): # can also put a full path here for name in f: # full path to original image original_fn = r + os.sep + name # path + hex number of counter + extension of file new_fn = r + os.sep + hex(counter).lstrip("0x").upper() + os.path.splitext(name)[-1] # rename, status print, incrementing counter os.rename(original_fn, new_fn) print(f"Renamed {original_fn} > {new_fn}") counter += 1Aquí hay una solución para cambiar primero el nombre de todos los archivos a archivos temporales con cadenas aleatorias adjuntas, y luego cambiarles el nombre a números hexadecimales basados en un contador. Espero que eso resuelva tus problemas:
import os import random import string for r, d, f in os.walk(r"Images"): for name in f: rnd_string = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(12)) original_fn = r + os.sep + name new_fn = r + os.sep + rnd_string + name os.rename(original_fn, new_fn) print(f"Temp. rename {original_fn} > {new_fn}") counter = 1 for r, d, f in os.walk(r"Images"): # can also put a full path here for name in f: original_fn = r + os.sep + name new_fn = r + os.sep + hex(counter).lstrip("0x").upper() + os.path.splitext(name)[-1] os.rename(original_fn, new_fn) print(f"Final rename {original_fn} > {new_fn}") counter += 1Hay debajo de un script bash. Cambia los valores de dest_dir y source_dir
No olvides hacerlo ejecutable con chmod +x flattener.sh
#!/bin/env bash dest_dir="/var/tmp/flat-files" source_dir="parent-dir" if [ ! -d "${dest_dir}" ] ; then mkdir -p "${dest_dir}" fi if [ ! -f "${dest_dir}"/index.dat ] ; then printf "1" > "${dest_dir}"/index.dat || exit 1 fi find "${source_dir}" -type f -print0 |\ xargs -0 bash -c ' \ for filename ; do \ index=$(cat '"${dest_dir}"'/index.dat) ;\ printf "%d" $((index+1)) > '"${dest_dir}"'/index.dat ;\ if [[ "${filename}" =~ [.] ]] ; then \ extension=."${filename##*.}" ;\ else \ extension="" ;\ fi ;\ mv -vu "${filename}" '"${dest_dir}"'/$(printf "%X" $index)"${extension}" ;\ done' flattenerCon bash >= 4.0 y cp (sin mv / rename ):
shopt -s globstar unset int for i in **/*.jpg; do ((int++)) printf -v hex '%x' "$int" echo cp -v "$i" "FolderAllTogether/${hex^^}.jpg" done Si la salida se ve bien, elimine echo .