Renombrar archivos y directorios recursivamente bajo ubuntu / bash


Quiero cambiar el nombre de todos los archivos y directorios que contienen la palabra "special" a "regular". Debe mantener la sensibilidad de mayúsculas y minúsculas para que " Especial "no se convierta en"regular".

¿Cómo puedo hacer esto en bash recursivamente?

Author: Tom, 2013-02-22

5 answers

Intente hacer esto (requerir bash --version >= 4):

shopt -s globstar
rename -n 's/special/regular/' **

Retire el interruptor -n cuando sus pruebas estén BIEN

Hay otras herramientas con el mismo nombre que pueden o no ser capaces de hacer esto, así que tenga cuidado.

Si ejecuta el siguiente comando (GNU)

$ file "$(readlink -f "$(type -p rename)")"

Y tienes un resultado como

.../rename: Perl script, ASCII text executable

Y que no contenga:

ELF

Entonces esta parece ser la herramienta correcta=)

Si no, para que sea el valor predeterminado (por lo general ya el caso) en Debian y derivado como Ubuntu:

$ sudo update-alternatives --set rename /path/to/rename

(reemplace /path/to/rename a la ruta de su comando perl's rename.


Si no tiene este comando, busque en su gestor de paquetes para instalarlo o hágalo manualmente


Por último, pero no menos importante, esta herramienta fue escrita originalmente por Larry Wall, el padre de los Perl.

 65
Author: Gilles Quenot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-19 18:29:13

Una solución usando find:

Para renombrar solo archivos :

find /your/target/path/ -type f -exec rename 's/special/regular/' '{}' \;

Para renombrar directorios solamente :

find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \+

Para cambiar el nombre de ambos archivos y directorios :

find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+
 83
Author: speakr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-06 12:33:33

Si no te importa instalar otra herramienta, entonces puedes usar rnm :

rnm -rs '/special/regular/g' -dp -1 *

Pasará por todos los directorios/subdirectorios (debido a -dp -1) y reemplazará special con regular en sus nombres.

 4
Author: Jahid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-07 09:33:53

@la respuesta de speakr fue la clave para mí.

Si usa-execdir para transformar archivos y directorios, también querrá eliminar -type f del ejemplo mostrado. Para deletrearlo, use:

find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+

También, considere agregar g (global) a la expresión regular si desea reemplazar todas las ocurrencias de special con regular en un nombre de archivo dado y no solo la primera ocurrencia. Por ejemplo:

find /your/target/path/ -execdir rename 's/special/regular/g' '{}' \+

Transformará special-special.jpg a regular-regular.jpg. Sin la bandera global, terminarás con regular-special.jpg.

Para su información: GNU Rename no está instalado de forma predeterminada en Mac OSX. Si está utilizando el gestor de paquetes Homebrew , brew install rename remediará esto.

 2
Author: U007D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:07

Para aquellos que solo desean cambiar el nombre de los directorios, puede usar este comando:

find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;

El tipo de nota es ahora d para directorio, y usando -execdir.

No he sido capaz de averiguar cómo cambiar el nombre de los archivos y directorios en una sola pasada, sin embargo.

Alguien comentó anteriormente que una vez que cambió el nombre de la carpeta raíz, ya no podía atravesar el árbol de archivos. Hay un interruptor -d disponible que hace un recorrido de profundidad desde abajo hacia arriba, por lo que la raíz se renombraría lo último que creo:

find -d /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;

De la página de manual (man find):

 -d      Cause find to perform a depth-first traversal, i.e., directories are visited in post-order and all entries in a directory will be
         acted on before the directory itself.  By default, find visits directories in pre-order, i.e., before their contents.  Note, the
         default is not a breadth-first traversal.
 0
Author: LokMac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-11 04:31:15