Quiero cambiar el nombre de varios archivos en el mismo directorio usando secuencias de comandos Bash. Los nombres de los archivos son los siguientes:
file2602201409853.p file0901201437404.p file0901201438761.p file1003201410069.p file2602201410180.p
Quiero cambiar el nombre al siguiente formato:
file2503201409853.p file2503201437404.p file2503201438761.p file2503201410069.p file2503201410180.p
Estaba leyendo sobre el comando de cambio de nombre y trato de hacerlo de esta manera, pero no hace nada, creo que tengo preguntas sobre la sintaxis. Luego leí que puedes hacer un bucle usando el comando mv de la siguiente manera:
for file in cmpsms*2014*.p; do mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}" done
Pero no puedo cambiar el nombre de los archivos. ¿Qué estoy haciendo mal?
Comentarios
Respuesta
Hizo bien en considerar cambiar el nombre primero. La sintaxis es un poco extraña si no está acostumbrado a las expresiones regulares, pero es, con mucho, la ruta más rápida / corta una vez que sabe lo que está haciendo:
rename "s/\d{4}/2503/" file*
Eso simplemente coincide con los primeros 4 números y los cambia por los que usted especificó.
Y un arnés de prueba (-vn
significa ser detallado pero no hacer cualquier cosa) usando sus nombres de archivo:
$ rename "s/\d{4}/2503/" file* -vn file0901201437404.p renamed as file2503201437404.p file0901201438761.p renamed as file2503201438761.p file1003201410069.p renamed as file2503201410069.p file2602201409853.p renamed as file2503201409853.p file2602201410180.p renamed as file2503201410180.p
Comentarios
- Nota que este es el cambio de nombre de Perl en Debian y derivados (Ubuntu, Mint,…). En otras distribuciones de Linux,
rename
es una herramienta de cambio de nombre de archivos completamente diferente (que Debian incluye comorename.ul
). - Si su falta distributiva de dicha herramienta, mire la respuesta de @Michael Campbell. Creo que todos los distributivos reemplazan el valor predeterminado
rename
como lo hizo Debian.
Respuesta
Esto debería funcionar:
for f in file*; do mv $f ${f/${f:4:8}/25032014}; done
Reemplaza la cadena entre el cuarto y el duodécimo carácter por «25032014».
Comentarios
- esto
for f in file*; do mv $f ${f/${f:4:4}/2503}; done
también funciona. - Eso ' s agradable. Si solo desea reemplazar una palabra por palabra, funciona como sed. p.ej.
for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
- @Eric: publiqué tu respuesta como alternativa porque creo que es ' más clara y elegante . Si también desea publicarlo como respuesta, ' eliminaré el mío. ¡Gracias!
- ¿Por qué faltan comillas dobles ?
- Me da un error: " mv: target ' FILE_NAME ' no es un directorio "
Respuesta
Esta es realmente la respuesta de @Eric desde arriba, pero es una respuesta elegante, así que Lo voy a publicar como una respuesta adecuada para llamar más la atención sobre él.
for f in *Huge*; do mv "$f" "${f/Huge/Monstrous}"; done
Respuesta
ptrn="file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p" path=/dir ( set -- "${path}/"${ptrn} ; for f ; do { echo "mv ${path}/${f} \ ${path}/file25032014${f#2014}" } ; done )
Esto debería funcionar. Nota: no tengo el hábito de entregar comandos mv en masa, como está escrito, es solo un eco. Tú» tendré que resolver eso antes de que funcione.
Respuesta
Una forma nativa simple de hacerlo sin bucles, con recorrido de directorio :
find -type f | xargs -I {} mv {} {}.txt
Cambiará el nombre cada archivo en su lugar.
Y debajo de un trabajo ejemplo con paralelización :
find -name "file*.p" | parallel "f="{}" ; mv -- {} ${f:0:4}2503${f:8}"
Comentarios
- Fue un primer enfoque fácil para imaginar una mejor solución. Si desea un comando que funcione, haga:
-
find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'
Responder
Si encuentra que hace mucho este tipo de cosas, busque «rename.pl». Es un script de Perl, pero le permite simplemente alimentarlo con código Perl (como una expresión ///), y hará un cambio de nombre masivo basado en esa expresión o código.
Existe una versión básica aquí: http://stackoverflow.org/wiki/Rename.pl pero hay otras versiones flotando en la red. Ha existido durante siglos y siglos.
*
?