Qual é a diferença entre 'renomear' e 'mv'?

12

Não está completamente claro para mim, mas qual é a diferença entre mve rename(de util-linux-ng 2.17.2as /usr/bin/rename)? Há vantagens de um sobre o outro além de renameaceitar expressões regulares e mvnão? Eu acredito renameque também pode lidar com vários renomeamentos de arquivos de uma só vez, enquanto mvque não faz isso.

Não consegui encontrar uma indicação clara em suas manpáginas, o que mais os diferencia ou através de alguma investigação por conta própria.

Urda
fonte
2
Vamos ter certeza de que estamos falando das mesmas coisas; quais são as saídas type -a renamee rename --version?
Jeff Schaller
@JeffSchaller É mais uma curiosidade da minha parte, mas em uma das minhas máquinas * nix eu recebo rename is /usr/bin/renamee, rename (util-linux-ng 2.17.2)respectivamente.
Urda
6
Existem algumas renomeações diferentes por aí , e poderia ter sido um apelido / função / script, então eu só queria ter certeza de que sabíamos o que era. Obrigado! Sinta-se à vontade para editar essas saídas em sua pergunta.
Jeff Schaller
@JeffSchaller não se preocupe, na verdade este link foi um que eu acabei de descobrir que me mostrou renamesignificados diferentes em diferentes distros.
Urda
5
Parece que sua pergunta contém a resposta. "Qual é a diferença entre um jato e um triciclo, além do fato de que um jato pode voar e pode ser milhares de vezes mais rápido?" :-) ⁠
G-Man diz 'Reinstate Monica'

Respostas:

21

É basicamente o que diz na tampa, para ambos.

mvé um utilitário padrão para mover um ou mais arquivos para um determinado destino. Pode ser usado para renomear um arquivo, se houver apenas um arquivo para mover. Se houver vários, mvsó funcionará se o destino for o diretório e moverá os arquivos para lá.

Então mv foo bar, moverá o arquivo foopara o diretório bar(se existir) ou renomeie foopara bar(se barnão existir ou não for um diretório). mv foo1 foo2 barapenas moverá os dois arquivos para o diretório barou reclamará se barnão for um diretório.

mvchamará a rename()função de biblioteca C para mover os arquivos e, se isso não funcionar (eles estão sendo movidos para outro sistema de arquivos), ele copiará os arquivos e removerá os originais.

Se tudo o que você tem é mve deseja renomear vários arquivos, será necessário usar um loop de shell. Há uma série de perguntas sobre isso aqui no site, veja por exemplo este , este , e outros .


Por outro lado, os vários renameutilitários renomeiam os arquivos individualmente.

O renamefrom util-linux que você menciona faz uma simples substituição de string, por exemplo rename foo bar *, mudaria foobarpara barbare asdffoopara asdfbar. Ele não , no entanto, ter uma expressão regular!

O utilitário de renomeação do Perl ( ou várias instâncias dele ) usa uma expressão Perl para transformar os nomes dos arquivos. Provavelmente, usaremos um comando, em que o padrão é uma expressão regular.s/pattern/replacement/

Tanto a renomeação do util-linux quanto a renomeação do Perl podem ser usadas para mover arquivos para outro diretório ao mesmo tempo, fazendo as alterações apropriadas no nome do arquivo, mas é um pouco estranho. Além de chamar rename()os arquivos, a mudança de um sistema de arquivos para outro não funciona.

Quanto ao que renamevocê possui, isso pode depender da sua distribuição e / ou do que você instalou. A maioria deles suporta rename --version, então use isso para identificar qual deles você possui.

ilkkachu
fonte
Não apenas 'expressão regular', mas funciona se necessário
Gilles Quenot
@GillesQuenot, bem, sim, você poderia fazer, por exemplo, rename '$_=lc' *nomes de arquivos em minúsculas. Mas acho que o caso mais comum é usar s///(que mencionei) e a parte do padrão é uma regex; Eu não acho que você pode usar uma função lá. Você poderia fazê-lo na peça de substituição, no entanto.
precisa saber é o seguinte
@MyWrathAcademia, Esse primeiro exemplo na página de manual funciona para mim (ele faz as coisas de maneira diferente da outra). Além disso, o motivo pelo qual vinculei as páginas de manual do Debian é que pelo menos lá ficou muito claro que a página de manual rename.ulé e será para a versão util-linux, e não para nenhuma outra.
Ilkkachu
@ilkkachu, você se importa de adicionar uma explicação ao primeiro exemplo, na sua resposta ou em um comentário. É diferente do exemplo em man renamepor isso seria bom saber o seu entendimento do exemplo debian
MyWrathAcademia
@MyWrathAcademia, presumi que você quis dizer o rename foo foo0 foo?; rename foo foo0 foo??exemplo, já que essa foi a única diferença entre as duas páginas de manual que vi. Esse par de comandos funciona porque o primeiro adiciona zero aos nomes de cada nome de arquivo de um dígito e, depois disso, o segundo adiciona (outro) zero a cada nome de arquivo de dois dígitos. Esse segundo conjunto inclui os arquivos renomeados pelo primeiro comando. Usando rename foo foo00 foo?como o primeiro comando também funciona, ele apenas adiciona dois zeros de uma só vez.
Ilkkachu
2

mvsimplesmente altera o nome do arquivo (também pode movê-lo para outro sistema de arquivos ou caminho). Você atribui um nome antigo e um novo nome e altera o arquivo para o novo nome ou local. renameé usado para fazer alterações de nomeação em massa. Digamos que você tinha mil arquivos, foo000.logatravés de foo999.loge você queria mudá-los para bar000.logAtravés bar999.log. Com mvvocê teria que fazer mv foo000.log bar000.log, mv foo001 bar001.logetc., ou então escrever um script. Com renamevocê simplesmente faz rename foo bar foo*.log, e pronto, milhares de arquivos são alterados em um instante! Muito legal. Confira a man renamepágina novamente para obter detalhes.

eewanco
fonte
2

mv

É uma linha de comando básica projetada para fazer uma coisa e fazer bem (filosofia Unix): mover arquivo (s) ou diretório (s) .

Você pode hackear STDOUT& STDIN¹ para modificar rapidamente a string de destino, mas não é apenas um hack inteligente

renomear (o de Perl)

Atenção Existem outras ferramentas com o mesmo nome que podem ou não conseguir fazer isso, portanto, tenha cuidado.

Quando as pessoas falam rename, pensamos neste, não no ELF, menos poderoso (mágica?).

Não é básico, é Perl. Você pode passar algumas funções do Perl por dentro, e é extremamente poderoso.

Considere este exemplo:

Você deseja renomear um monte de arquivos como

foobar_1.txt
foobar_2.txt
foobar_3.txt

Você pode acrescentar zeros aos dígitos da sprintf()seguinte forma (usando regex, heh, é Perl: D):

rename 's/(\d+)/sprintf("%04d", $1)/e' foobar_*.txt

Agora você tem :

foobar_0001.txt
foobar_0002.txt
foobar_0003.txt

Não é realmente um comando básico, não é?

não é realmente projetado para mover dir (s) , mas pode fazê-lo:

$ mkdir -p /tmp/foo/bar/base
$ touch /tmp/foo/bar/base/file
$ rename 's!/tmp/foo/bar/base/file!/tmp/file!' /tmp/foo/bar/base/file

O arquivo movido

/tmp/file

¹ algum código que vemos nos *.stackexchange.*sites

insira a descrição da imagem aqui

for FILE in `ls *.txt`
do
    mv ${FILE} `echo ${FILE} | sed 's/anything_ugly/anything_still_ugly/'`
done

Não é o caminho a seguir , é simplesmente um buggy, apenas para explicar por que usar a ferramenta certa no momento certo

Gilles Quenot
fonte
+1 por sprintfing com renomeação
Archemar 04/04/19
-1

mv move ou renomeia arquivos e diretórios e fará o backup deles; renomear apenas renomeia arquivos.

O mv tem mais recursos e opções. Veja os comutadores nas páginas de manual de cada um para ver as diferenças de recursos. Vamos dar uma olhada usando man no Ubuntu 18.04LTS (sua milhagem pode variar dependendo da versão de cada pacote):

opções mv (omitindo ajuda e versão)

   --backup[=CONTROL]  
          make a backup of each existing destination file  

   -b     like --backup but does not accept an argument  

   -f, --force  
          do not prompt before overwriting  

   -i, --interactive  
          prompt before overwrite  

   -n, --no-clobber  
          do not overwrite an existing file  

  If you specify more than one of -i, -f, -n, only the final one takes effect.  

   --strip-trailing-slashes  
          remove any trailing slashes from each SOURCE argument  

   -S, --suffix=SUFFIX  
          override the usual backup suffix  

   -t, --target-directory=DIRECTORY  
          move all SOURCE arguments into DIRECTORY  

   -T, --no-target-directory  
          treat DEST as a normal file  

   -u, --update  
          move only when the SOURCE file is newer than the destination file or when the destination file is missing  

   -v, --verbose  
          explain what is being done  

   -Z, --context  
          set SELinux security context of destination file to default type  

renomear opções (omitindo ajuda e versão)

   -s, --symlink   
          Do not rename a symlink but its target.  

   -v, --verbose  
          Show which files where renamed, if any.  

   -n, --no-act  
          Do not make any changes.  

   -o, --no-overwrite  
          Do not overwrite existing files.            
K7AAY
fonte
3
Defina 'mais poderoso'. O mv suporta regex como renomear?
Gilles Quenot
Como o questionador afirmou, não.
K7AAY
2
Uau, que argumento
Gilles Quenot 04/04
1
Dar crédito onde o crédito é devido.
K7AAY 04/04/19