Línea de comando mover archivo con ruta de directorio larga sin repetir ruta de directorio

16

¿Hay alguna forma de ejecutar un mvcomando sin escribir la ruta completa en el segundo argumento?

Ejemplo:

mv my/file/that/has/a/really/long/path/foo.bar some_magic_operator_that_means_the_same_directory/foo.baz

Finbarr
fuente
1
¿Alguna razón por la que no puedes simplemente cdir al directorio y mvdesde allí?
zpletan
Con frecuencia me encuentro ejecutando este tipo de comandos en varios directorios en mi trabajo diario. A menudo necesito ejecutar varios comandos desde un directorio padre dado.
Finbarr
De alguna manera encontré eso usando !! (signos de doble exclamación) en un terminal utiliza para ejecutar el último comando ejecutado. También puede agregar parámetros / texto al último comando, pero nunca intentó cambiar / eliminar texto del último comando. Pruébalo y, si tienes éxito, dejaré esto como una respuesta. ¡Buena suerte!
Geppettvs D'Constanzo

Respuestas:

32

Puedes usar la expansión de llaves de bash. Esta:

mv my/file/that/has/a/really/long/path/foo.{bar,baz}

se expandirá a:

mv my/file/that/has/a/really/long/path/foo.bar my/file/that/has/a/really/long/path/foo.baz

y luego mvse ejecuta con esos dos argumentos. Consulte http://wiki.bash-hackers.org/syntax/expansion/brace para obtener más información sobre la expansión de llaves.

geirha
fuente
3
Eso es glorioso No sabía que podías hacer eso.
Finbarr
5

Como alternativa a la expansión de llaves, puede usar las características de expansión del historial de bash shell :

  • ! introduce una expansión de la historia
  • # designador de eventos que denota el comando actual
  • $ designador de palabras que se refiere al último argumento

Puede realizar sustituciones en la expansión utilizando una s/pattern/replacementsintaxis de tipo sed, por ejemplo

somecommand path/to/foo.bar !#$:s/.bar/.baz

Ex.

$ mv -v somepath/Original/Dir3/SubDir1/foo.bar !#$:s/.bar/.baz
mv -v somepath/Original/Dir3/SubDir1/foo.bar somepath/Original/Dir3/SubDir1/foo.baz
'somepath/Original/Dir3/SubDir1/foo.bar' -> 'somepath/Original/Dir3/SubDir1/foo.baz'

Si desea la ruta específicamente (por ejemplo, a mvun archivo con un nombre completamente diferente que no se obtiene fácilmente por sustitución), puede usar el hmodificador:

$ mv -v somepath/Original/Dir3/SubDir1/foo.baz !#$:h/baz.foo
mv -v somepath/Original/Dir3/SubDir1/foo.baz somepath/Original/Dir3/SubDir1/baz.foo
'somepath/Original/Dir3/SubDir1/foo.baz' -> 'somepath/Original/Dir3/SubDir1/baz.foo'

Para otras opciones, incluidas readlinelas combinaciones de teclas para tirar del último argumento, vea ¿Cómo repetir el parámetro actualmente escrito en la consola bash?

conductor de acero
fuente
2

Puedes probar:

pushd .
cd /really/long/directory/name/
mv whatever.1 whatever.2
popd
zpletan
fuente
2

Con una variable

  1. Guarde el directorio en una variable: `DIR=./really/long/path/
  2. usar movimiento: mv "$DIR"foo.bar "$DIR"foo.bz

En una línea: DIR=./really/long/path/; mv "$DIR"foo.bar "$DIR"foo.bz


Cambio de directorio

  1. También puede cdir al directorio en el que desea trabajar:cd ./really/long/path
  2. luego cambie el nombre del archivo: mv foo.bar foo.bz

En una línea: cd ./really/long/path && mv foo.bar foo.bz

danjjl
fuente
1
ese segundo parece familiar ;-)
zpletan
2
Mejor uso &&en esa última línea. De lo contrario, si cdfalla, mvse ejecutará en el directorio incorrecto, posiblemente sobrescribiendo un archivo. Con cd ./really/long/path && mv foo.bar foo.baz, mvsolo se ejecutará si cdlogra cambiar el directorio.
geirha
-3

Puede alias comando para acortar el nombre del directorio:

alias src='/directory/name/of/source'
alias dst='/directory/name/of/destination'
mv src dst
shantanu
fuente
1
-1 alias test='/var/log' ; cd testda -bash: cd: test: No such file or directory.
zpletan