En bash, ¿cómo puedo cambiar el nombre de un archivo sin repetir la ruta? [duplicar]

39

Posible duplicado:
reutilizar texto en un comando bash

Si quiero cambiar el nombre de un archivo a unos pocos directorios de profundidad, ¿cómo puedo evitar repetir la ruta?

Por ejemplo:

mv path/to/old_filename.txt path/to/new_filename.txt

Me pregunto si hay una manera de hacer esto:

mv path/to/old_filename.txt (?)new_filename.txt

¿Dónde (?)habría alguna forma de decir "en el mismo directorio"?

Nathan Long
fuente

Respuestas:

26

Usando la expansión del historial bash :

mv path/to/oldfile !#:1:h/newfile

donde !#:1:hsignifica: desde la línea que está escribiendo actualmente ("! #"), tome la primera palabra (": 1"), luego tome solo el componente de ruta (": h" - el encabezado).

Glenn Jackman
fuente
Esto es lo más cercano a lo que el interrogador original asumió que podría ser la solución, y es útil saberlo, entonces +1.
crazy2be
2
¡Guay! Creo que el método de expansión de llaves de Darth es más fácil, pero esto es exactamente lo que pedí.
Nathan Long
Hoy he aprendido dos cosas nuevas geniales. Además, siempre pensaré en la expansión de llaves como "la expansión de llaves de Darth" porque suena increíble.
PileOfMush
62

Puede usar la expansión de llaves: mv path/to/{old_filename.txt,new_filename.txt}

Aquí hay un enlace a la guía de GNU sobre la expansión de llaves en el shell bash, que define una lista de sustitutos y le dice a bash que repita el parámetro usando un sustituto diferente cada vez que se repite.

Por ejemplo,

a{b,c,dd,e}

se ampliará a

ab ac add ae

La única advertencia es que las repeticiones expandidas deben poder seguirse entre sí como argumentos para el programa de destino.

Darth Android
fuente
55
O se mantienen al mínimo: mv path/to/{old,new}_filename.txt. Esto también ayuda a la reversión u otros tipos de cerca de la repetición del comando. Muchas veces lo he hecho mv /etc/X11/xorg.conf{,.backup}, por ejemplo , poder revertir el proceso con el simple cambio mv /etc/X11/xorg.conf{.backup,}.
Daniel Andersson
26

La respuesta de Darth anterior es inteligente, pero si desea utilizar un enfoque con cd, también podría considerar usar una subshell:

(cd path/to && mv old_filename.txt new_filename.txt)

Debido a que el cambio de directorio tiene lugar en el subshell, en realidad no cambiará los directorios en su shell interactivo.

mlc
fuente
1
Inconveniente significativo: no puede utilizar la finalización de tabulación para old_filename.txt.
bluenote10
9

Otra alternativa que es útil, si va a hacer varios comandos en el directorio, es esta:

pushd /path/to
mv oldfile newfile
...
popd
KeithB
fuente
5

Me gusta la respuesta de @ Darth . Aquí hay una alternativa:cd path/to && mv oldfile newfile && cd -

Glenn Jackman
fuente
1
Tenga en cuenta que si mvfalla (por ejemplo, sin permisos), quedará en el path/todirectorio. Puede intentar cd path/to && mv oldfile newfile ; cd -asegurarse de cd -que siempre se ejecute, excepto si cd path/to(sin permisos) falla, seguirá ejecutándose cd -e irá al directorio anterior que no es deseado. La respuesta de subshell mlc (+1) es mejor. Supongo cd . && cd path/to && mv oldfile newfile ; cd -que funcionaría el 99.9% del tiempo (con cd .solo fallar si usted o sus permisos de directorios actuales cambiaron; y en ese caso, ir a un directorio diferente no es un mal resultado.
Dr. jimbob