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.

Richard Hoskins
fonte
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.

falstro
fonte
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
Dennis Williamson
fonte
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

TRS-80
fonte
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.

freiheit
fonte
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
xalupadas
fonte
1

Se você usa o Zsh, pode usar o 'zmv'

Martin
fonte
1

A melhor ferramenta é mmv .

mmv \*.htm #1.html

Outros exemplos de uso (e de outras ferramentas) no " Resumo das Ferramentas de Linha de Comando do GNU / Linux ".

bortzmeyer
fonte
11
Seu exemplo de uso falha. Você precisa escapar #.
Cristian Ciupitu 12/09/09
Não, ele funciona (eu SEMPRE teste antes de publicar no SuperUser). A necessidade de escapar # depende do shell que você usa (eu uso o zsh).
Bortzmeyer
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
Cristian Ciupitu
fonte