Arquivo mv do Linux com nome longo

19

No Linux, às vezes renomeio arquivos como este:

mv dir1/dir2/dir3/file.txt  dir1/dir2/dir3/file.txt.old

Note que quero apenas renomear o arquivo, não movê-lo para outro diretório.

Existe um comando que me permita fazer uma versão abreviada desse comando? Estou pensando em algo como:

mv dir1/dir2/dir3/file.txt  file.txt.old

ou talvez até algo parecido com (apenas acrescentar ao nome):

mv dir1/dir2/dir3/file.txt  {}.old

Meu objetivo é não precisar especificar o caminho completo novamente.

Eu sei que esses "exemplos" que escrevi não funcionam, mas é apenas uma ideia do que eu quero realizar.

Eu não quero ter que entrar no diretório.

    
por santiago arizti 20.01.2018 / 18:52

7 respostas

44

para um único arquivo tente

mv dir1/dir2/dir3/file.{txt,txt.old}

em que a construção X{a,b} se expande para Xa Xb , você pode ter uma visualização usando

echo dir1/dir2/dir3/file.{txt,txt.old}

para ver se isso se ajusta à sua necessidade.

nota:

  1. que para vários arquivos

    mv dir1/dir2/dir3/file{1,2,3}.{txt,txt.old}
    

é improvável que se expanda para o que você deseja. (isso se expandirá para uma mistura de arquivo.txt file1.txt.old file2.txt ...)

  1. {txt,txt.old} pode ser reduzido para {,.old} conforme comentário

  2. se o nome do diretório não for ambíguo, o caractere curinga poderá ser usado.

    mv *1/*2/d*/*.{,old}
    

para uso de vários arquivos rename

rename -n s/txt/old.txt/ dir1/dir2/dir3/file*.txt 

solte -n para ter renomeação efetiva.

    
por 20.01.2018 / 19:14
6

O comando rename renomeia todos os arquivos correspondentes. Seu principal objetivo é renomear vários arquivos, mas se a expressão Perl corresponder apenas a um arquivo, ele renomeará apenas esse único arquivo. Para detalhes e sintaxe específica da distribuição, leia a página de manual: man rename .

Exemplo de uso: renomeie "/path/file.txt" para "/path/file.txt.old":

rename 's/file.txt/file.txt.old/g' /path/file.txt

Notação mais curta (graças ao shalomb):

rename 's/$/.old/' /path/file.txt
rename '$_.=".old"' /path/file.txt

Para uma execução a seco, use rename -n .

Mais exemplos e detalhes podem ser encontrados no link

    
por 20.01.2018 / 19:05
4

Para um caso único, se eu não quiser alterar meu diretório atual, posso usar apenas um sub-shell:

(cd dir1/dir2/dir3/ && mv file.txt file.txt.old)

Porque você cd dentro do sub-shell, você não mudou seu diretório no seu shell real

    
por 21.01.2018 / 20:56
4

Eu gosto da solução do @archemar de usar {} expansão, porque você pode usá-lo quando já tiver iniciado sua linha de comando. Aqui estão algumas outras possibilidades de completude:

F="dir1/dir2/dir3/file.txt" ; mv "$F" "$F.old"

(aspas são necessárias apenas se você tiver espaços ou outros caracteres de quebra de palavras no nome)

mymv() {
    mv "$1/$2" "$1/$3"
}

mymv dir1/dir2/dir3 file.txt file.txt.old
mymv dir5/dir6/dir7 file.txt file.txt.old

Notas:

  • Esta é a sintaxe bash, você pode estar usando outro shell
  • mymv pode ser qualquer string razoável, usei mymv para "my move".
  • A definição da função pode ser colocada em seu .bash_profile

Outro:

cd dir1/dir2/dir3 ; mv file.txt file.txt.old ; cd -

mas

(cd dir1/dir2/dir3/ && exec mv file.txt file.txt.old)

(de @Adam e @CharlesDuffy) é indiscutivelmente melhor caso o cd falhe.

    
por 21.01.2018 / 15:55
2

Se você quiser entrar no subdiretório para encurtar o comando mv , mas quiser voltar ao diretório atual depois, há duas maneiras de fazer isso. Uma é colocar o cd e mv em uma subcamada (como já foi sugerido).

O outro é usar pushd e popd para alterar os diretórios:

pushd dir1/dir2/dir3/; mv file.txt file.txt.old; popd

O comando pushd é como cd , exceto que primeiro envia o nome do diretório atual para uma pilha. popd remove o nome do topo da pilha e muda para esse diretório.

    
por 22.01.2018 / 05:53
2

Gostaria apenas de fazer

cd dir1/dir2/dir3/
mv file.txt file.txt.old
cd ~- # go to the most recent directory
    
por 22.01.2018 / 14:05
0

A solução envolvendo: mv something{.txt,.txt.old} está usando um "bashism". Se você quiser uma maneira mais portátil, usando manipulações de variáveis comuns:

# rename all files "file*.txt" of directory /dir1/dir2/dir3 into file*.txt.old:
for f in dir1/dir2/dir3/file*.txt ; do
  mv "$f" "${f/.txt/.txt.old}"  # note there are no terminating "/"
done


# "${var/A/B}" is the content of var with the first occurence of "A" replaced by "B"
    
por 23.01.2018 / 11:14