Tengo un montón de carpetas con varios nombres, por ejemplo
2013-02 Snow and birds
PICT0001.jpg
PICT0002.jpg
2013-06 Bicycle trip
edited_panorama.jpg
From phone
DCIM0001.jpg
DCIM0002.jpg
DCIM0003.jpg
From camera
DSLR
PICT0001.raw
PICT0002.raw
Compact
S0000001.jpg
Como puede ver, la estructura general es un nivel variable de subcarpetas anidadas que contienen imágenes. Lo que quiero hacer es aplanar la estructura, agregando el nombre de cada nivel de subcarpetas al nombre del archivo, así:
2013-02 Snow and birds_PICT0001.jpg
2013-02 Snow and birds_PICT0002.jpg
2013-06 Bicycle trip_edited_panorama.jpg
2013-06 Bicycle trip_From phone_DCIM0001.jpg
2013-06 Bicycle trip_From phone_DCIM0002.jpg
2013-06 Bicycle trip_From phone_DCIM0003.jpg
2013-06 Bicycle trip_From camera_DSLR_PICT0001.raw
2013-06 Bicycle trip_From camera_DSLR_PICT0002.raw
2013-06 Bicycle trip_From camera_Compact_S0000001.jpg
¿Cómo se puede lograr esto utilizando un script de Terminal o cualquier otro tipo de script? He encontrado algunas soluciones similares, pero todas parecen depender de un nivel fijo de subcarpetas, mientras que mi estructura de carpetas varía.
Difícil, especialmente si desea mantener todos los espacios, etc. Ejecute lo siguiente en el directorio superior (el que contiene, 2013-02 Snow and birds
etc.):
find . -type f -exec sh -c 'for f do x=${f#./}; echo mv "$x" "${x////_}"; done' {} +
La asignación a x
se deshace del principio ./
de find
, ${x////_}
reemplaza todas las apariciones (restantes) de /
con _
.
Además, he protegido lo real mv
con un correo electrónico echo
para que pueda verificar primero si los comandos se ven bien. Vuelva a ejecutar el comando sin echo
cambiar el nombre/mover los archivos.
La respuesta anterior de @nohillside es realmente genial. El único problema con esto es que no tiene en cuenta los archivos con espacios en ellos. Eso hará que algunos de los comandos fallen.
Así que estoy poniendo una respuesta aquí que también lo respaldaría.
Esto solo echo
mostrará los mv
comandos:
find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; echo "mv ${x// /\ } ${y////-}"; done' {} +
Esto solo echo
mostrará los mv
comandos en su mesa de trabajo directamente:
find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; echo "mv ${x// /\ } ${y////-}"; done' {} + | pbcopy
[Cuidado] Esto ejecutará inmediatamente los mv
comandos por usted:
find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; eval "mv ${x// /\ } ${y////-}"; done' {} +
echo
modo con una copia y pegado directos, funciona para la mayoría de los archivos, excepto para aquellos que escupen el error que explica el uso de mvusage: mv [-f | -i | -n] [-v] source target
Para los propósitos de este script, tenía todas sus carpetas contenidas en una carpeta llamada "Filez" en mi escritorio. Este script comienza con un cuadro de diálogo "elegir carpeta" para elegir la carpeta contenedora en la que residen las carpetas "2013-06 Viaje en bicicleta" y "2013-02 Nieve y pájaros". Esto devolverá todos los archivos individuales dentro de todas las carpetas y subcarpetas, cuyos nombres desea cambiar.
set mainFolder to choose folder
set posixPathOfMainFolder to POSIX path of mainFolder
tell application "Finder"
set theNames to files of entire contents of mainFolder as alias list
end tell
set newFileNames to {}
repeat with aFile in theNames
set text item delimiters to {posixPathOfMainFolder, "/"}
set aFile to POSIX path of aFile
set tempName to text items -1 thru 2 of aFile
set text item delimiters to "_"
set end of newFileNames to tempName as text
set text item delimiters to ""
tell application "Finder"
set the name of (aFile as POSIX file as alias) to last item of newFileNames as text
end tell
end repeat
tell application "Finder"
set theNames to files of entire contents of mainFolder as alias list
move theNames to mainFolder
delete folders of mainFolder
end tell
Magnus
Felipe
sin ladera