¿Cuál es la mejor manera de utilizar la expansión con comodines en bash cuando el origen y el destino son similares?

¿Cuál es la mejor manera de utilizar la expansión con comodines en bash cuando el origen y el destino son similares?

Supongamos que tengo estas carpetas:

$ ls
css-tricks/ django-tutorial/ good-tuts.txt js-tut/ tutorials/ tuts.txt

Algunos de estos tienen tuten sus nombres. Me gustaría mover todos los archivos/carpetas que tienen tutsus nombres a la carpeta tutorials/. Si ejecuto el comando

$ mv *tut* tutorials/

Recibo el siguiente mensaje:

mv: cannot move 'tutorials' to a subdirectory of itself, 'tutorials/tutorials'

¿Qué puedo hacer para evitar tal escenario?


Uno de los trucos que se me ocurren es cambiar el nombre de la carpeta de destino a otro temporalmente y, después de que se ejecute el comando, volver a cambiarlo al nombre deseado. Sin embargo, espero conocer una solución más elegante al problema.

Respuesta1

Personalmente, en una situación en la que estoy a punto de dar el comando de forma interactiva, lo haría mv *tut* tutorialsy esperaría recibir el error "no se puede mover". Es inofensivo y los demás archivos y directorios se habrán movido como se esperaba.

El estado de salida del comando será distinto de cero, lo que indica un error, pero como nada depende de ello, puede ignorarse.


En este caso, los demás nombres contienen un guión antes tut:

mv *-tut* tutorials

O, si también tienes cosas como python_tutlas que quieres mover, también permite un guión bajo:

mv *[_-]tut* tutorials

O, para requerir algún carácter adicional antes de la subcadena tut(que tutorialsno tiene),

mv *?tut* tutorials

Con un poco más de escritura y pensamiento, usando un patrón global extendido en bash:

shopt -s extglob
mv *tut!(orials*) tutorials

Esta segunda variación coincidirá con cualquier cosa que contenga la subcadena tutno seguida inmediatamente por la cadena orials. El patrón no coincidiría tutorialsy también se saltaría tutorials1, etc.

Respuesta2

También puedes usar find:

find . -type d -name "*tut*" -not -path "./tutorials" -exec mv -t "tutorials" {} +

Respuesta3

Recibo el siguiente mensaje:

mv: cannot move 'tutorials' to a subdirectory of itself, 'tutorials/tutorials'

Simplemente ignore el error.

No realmente. Sabes que recibirás el error porque el patrón global coincide con el objetivo. También sabes que no significa nada, ya que el sistema no puede mover el directorio dentro de sí mismo, y es lo suficientemente inteligente como para darse cuenta antes de estropear tu sistema de archivos.

Respuesta4

La forma más sencilla es cambiar el nombre del directorio de destino tutorials/a otro que no coincida en la expansión del nombre del archivo y cambiarle el nombre según desee después de realizar el movimiento.

información relacionada