No bash, como posso renomear um arquivo sem repetir o caminho? [duplicado]

39

Possível duplicado:
reutilizar texto em um comando bash

Se quiser renomear um arquivo com alguns diretórios, como evitar a repetição do caminho?

Por exemplo:

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

Gostaria de saber se existe uma maneira de fazer isso:

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

Onde (?)haveria uma maneira de dizer "no mesmo diretório".

Nathan Long
fonte

Respostas:

26

Usando a expansão do histórico do bash :

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

onde !#:1:hsignifica: na linha em que você está digitando ("! #"), pegue a primeira palavra (": 1") e, em seguida, pegue apenas o componente do caminho (": h" - a cabeça).

Glenn Jackman
fonte
Este é o mais próximo do que o questionador original supôs que a solução poderia ser e é útil saber, então +1.
crazy2be
2
Legal! Eu acho que o método de expansão da cinta de Darth é mais fácil, mas é exatamente isso que eu pedi.
Nathan Long
Eu aprendi duas grandes coisas novas hoje. Além disso, sempre pensarei na expansão da cinta como "expansão da cinta de Darth", porque parece incrível.
PileOfMush
62

Você pode usar a expansão de chaves: mv path/to/{old_filename.txt,new_filename.txt}

Aqui está um link para o guia GNU sobre expansão de chaves no shell bash, que define uma lista de substitutos e diz ao bash para repetir o parâmetro usando um substituto diferente cada vez que se repete.

Por exemplo,

a{b,c,dd,e}

será expandido para

ab ac add ae

A única ressalva é que as repetições expandidas devem poder se seguir como argumentos para o programa de destino.

Darth Android
fonte
5
Ou mantê-lo ao mínimo: mv path/to/{old,new}_filename.txt. Isso também ajuda a reversão ou outros tipos de repetição quase imediata do comando. Eu já fiz muitas vezes mv /etc/X11/xorg.conf{,.backup}, por exemplo , ser capaz de reverter o processo com a simples mudança mv /etc/X11/xorg.conf{.backup,}.
22812 Daniel Andersson
26

A resposta de Darth acima é inteligente, mas se você quiser usar uma abordagem cd, considere também usar um subshell:

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

Como a mudança de diretório ocorre no subshell, na verdade você não mudará os diretórios no seu shell interativo.

mlc
fonte
1
Desvantagem significativa: você não pode usar a conclusão de tabulação para old_filename.txt.
precisa saber é o seguinte
9

Outra alternativa útil, se você deseja executar vários comandos no diretório, é esta:

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

Eu gosto da resposta de @ Darth . Aqui está uma alternativa:cd path/to && mv oldfile newfile && cd -

Glenn Jackman
fonte
1
Observe que, se mvfalhar (por exemplo, sem permissões), você será deixado no path/todiretório. Você pode tentar cd path/to && mv oldfile newfile ; cd -garantir que cd -sempre seja executado, exceto se cd path/to(sem permissões) falhar, você ainda executará cd -e irá para o diretório anterior que é indesejado. A resposta do sub-shell mlc (+1) é melhor. Eu acho que cd . && cd path/to && mv oldfile newfile ; cd -iria funcionar 99,9% do tempo (com cd .só não se você ou seus diretórios atuais permissões alteradas, e, nesse caso, indo para a dir diferente não é tão ruim de um resultado.
dr jimbob