Renomeie um grupo de arquivos com um comando


38

Se eu tiver um grupo de arquivos com uma extensão .htm, como posso renomear todos eles para .html?

mv *.htm *.html

não funciona.


Apenas por uma questão de integridade, ren *.htm *.htmlfuncionará no Windows.
Brian Burns

Respostas:


50

Ou você pode usar o bash puro ... (exceto para mv, isto é ..)

for file in *.htm; do mv "$file" "${file%.htm}.html"; done

e evite as coisas desagradáveis ​​de nome de base. ;)

O Bash possui um amplo conjunto de opções de expansão variável. O usado aqui, '%', remove o menor sufixo correspondente do valor da variável. O padrão é um padrão glob, então ${file%.*}também funcionaria. O operador '%%' remove o maior sufixo correspondente e é intercambiável no exemplo acima, pois o padrão é fixo, mas ${file%%.*}.htmltransformaria abhtm em a.html.

Veja a seção de subestação variável da página de manual do bash para obter mais truques. Muito pode ser feito diretamente no bash.


11
Observe também que essas expansões de parâmetros não se limitam ao bash . Eles estão disponíveis em todos os reservatórios derivados de Bourne ( sh , ksh , bash , zsh , dash , ash , etc.). As expansões fazem parte da especificação POSIX para a "Shell Command Language" e são altamente portáteis.
Chris Johnsen

11

Não deve haver espaços, novas linhas ou outros espaços em branco nos nomes de arquivos, mas esta versão da resposta do freiheit lida com eles. Ele também usa em $()vez de backticks para facilitar a leitura, além de outros benefícios.

for file in *.htm
do
    mv "$file" "$(basename "$file" .htm).html"
done

Ainda melhor - para o caso especial de apenas adicionar até o fim:

for file in *.htm
do
    mv "$file" "${file}l"
done

11

rename(1)é um utilitário Perl que faz exatamente o que você deseja. Nesse caso:

rename 's/\.htm$/.html/' *htm

ou se você estiver usando subdiretórios também

(requer Bash 4.0 e a configuração globstar: shopt -s globstar)

rename 's/\.htm$/.html/' **/*htm


11
renomear é mais fácil, mas não é um programa unix padrão; pergunta original não especifica qual unix. Parece ser "nome de usuário" em alguns lugares.
freiheit

2
renamevem com perl, e basicamente todo unix vem com perl atualmente.
TRS-80

3
sim, mas nem todo unix inclui programas auxiliares como 'renomear' quando eles colocam perl no sistema. O OSX, por exemplo, não tem "renomear".
freiheit

11
@ William: A sintaxe de asterisco duplo está disponível apenas no Bash 4 e superior e somente se estiver ativada com shopt -s globstar(desativada por padrão). Além disso, o Linux e o Unix têm diretórios em vez de pastas.
Dennis Williamson

6
for file in *.htm; do
  mv $file `basename "$file" .htm`.html
done

Experimente com um echona frente da mvprimeira vez.

O problema com o original é que " mv *.htm *.html" tem os *s manipulados pelo shell, portanto o mvcomando simplesmente vê uma lista de todos os arquivos .htm e .html no diretório atual. Em outras palavras, algo como " mv foo.htm bar.htm stuff.htm six.htm file.htm". O mv sabe como lidar com mais de 2 argumentos se o último for um diretório.


11
Você deve citar "$ file", para manipular espaços.
Richard Hoskins

Sua descrição do problema original deve ser enfatizada mais fortemente. Esse comportamento de expansão de curinga do shell é surpreendente e não é intuitivo para quem vem do Windows, e entender o que o shell faz deixa claro por que o aplicativo original mvnão funciona.
Greg Hewgill 19/07/2009

3

Ainda outro exemplo puro de bash usando string replace.

for file in *.htm; do mv $file ${file/htm/html}; done

Extra - substitui todas as ocorrências de uma sequência

for file in *.htm; do mv $file ${file//htm/html}; done



0

O pacote util-linux-ng (no Fedora) possui um renamecomando semelhante ao mencionado pelo TRS-80 . Você pode usá-lo assim:

rename .htm .html *.html
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.