Adicionar extensão de arquivo a arquivos com bash

93

Qual é a boa maneira de adicionar a extensão de arquivo ".jpg" a arquivos sem extensão com o bash?

Adrian
fonte
3
mv "${file}" "${file}.jpg"?
onteria_
2
na sua opinião, o que é um "arquivo sem extensão"? É um arquivo sem um ponto no nome?
glenn jackman

Respostas:

116
for f in *.jpg; do mv "$f" "${f%.jpg}"; done
for f in *; do mv "$f" "$f.jpg"; done
Seth Robertson
fonte
8
o segundo é perfeito para renomear arquivos sem extensão! obrigado!
anon58192932
2
o segundo adiciona uma extensão em todos os arquivos, não apenas nos sem extensão
Jeff
5
assim como uma nota, "${f%.jpg}"é a manipulação de strings do shell bash. `$ {string% substring}` Exclui a correspondência mais curta de $ substring atrás de $ string.
Jichao
Aviso: Se você tiver uma pasta com extensões mistas, saiba que o acima adiciona .jpgaté mesmo aos arquivos normais.
sachinruk
61

Você pode usar renomear:

rename 's/(.*)/$1.jpg/' *
Kim Stebel
fonte
3
qual versão de renomear você está usando? O meu tem argumentos diferentes:rename from to file...
B Johnson
1
renomear está incluído no perl, que é a versão 5.10.1.
Kim Stebel
3
Isso funciona muito bem com a renomeação incluída no Ubuntu (e, portanto, estou supondo que todas as distros baseadas no Debian), muito menos prolixo do que a resposta do jm666.
Roger Heathcote
28

Outra maneira - sem loops

find . -type f -not -name "*.*" -print0 |\
xargs -0 file |\
grep  'JPEG image data' |\
sed 's/:.*//' |\
xargs -I % echo mv % %.jpg

Demolir:

  • encontre todos os arquivos sem extensão
  • verifique o tipo de arquivo
  • filtrar apenas arquivos JPG
  • excluir informações de tipo de arquivo
  • xargs executa o "mv" para cada arquivo

o comando acima é para simulação , depois disso você deve remover o "echo" antes de mv

EDITAR Algumas pessoas sugerindo que aqui é necessário "Quebrar argumentos de caminho entre aspas; evita divisão de argumento em caminhos com espaços" .

Normalmente, essa recomendação é verdadeira, neste caso não. Porque, aqui, o %foi substituído não pela expansão do shell, mas peloxargs internamente (diretamente), então o %será substituído corretamente mesmo com espaços nos nomes de arquivos.

Demonstração simples:

$ mkdir xargstest
$ cd xargstest

# create two files with spaces in names
$ touch 'a b' 'c d'

$ find . -type f -print
./c d
./a b
# notice, here are spaces in the above paths

#the actual xargs mv WITHOUT quotes
$ find . -type f -print | xargs -I % mv % %.ext

$ find . -type f -print
./a b.ext
./c d.ext
# the result is correct even in case with spaces in the filenames...
jm666
fonte
Você pode colocar isso em um loop e esses xargs são supérfluos. Eu gosto mais da resposta de Ryan nesta situação.
Lucius
1
@Lucius - btw, a questão quer arquivos "sem extensão" - então Ryan deve encontrar apenas aqueles ...
jm666
@ jm666 hey! como faço para modificar seu trecho de código para renomear todos os arquivos sem extensão em uma pasta para suas respectivas extensões. (Estou detectando extensões corretas pelo comando file -b $ filename.)
Soumyajit
24

Simples, faça cd para o diretório onde estão seus arquivos e:

for f in *;do mv $f $f.jpg;done
bharath
fonte
Por alguma razão, isso funciona para mim, mas a solução de Seth com aspas não. (OSX Mountain Lion bash)
delrocco
4
Seria melhor se usado for f in *;do mv "$f" "$f".jpg;donepara suportar espaços em nomes de arquivos.
Hritik de
Obrigado por esta solução simples e elegante - eu achei esta resposta várias vezes, mas não consigo memorizá-la. #dejavu
Tim Andersen
15

funcionamento a seco:

 rename -n s/$/.jpg/ *

renomeação real:

 rename s/$/.jpg/ *
Alexey
fonte
6
find . | while read FILE; do if [ $(file --mime-type -b "$FILE") == "image/jpeg" ]; then mv "$FILE" "$FILE".jpg; fi; done;
Ryan Li
fonte
1

No meu caso, eu não conhecia o tipo de arquivo, então usei o comando mv com a ajuda do comando file para examinar e possivelmente encontrar o tipo de arquivo. Esta solução pode não ser perfeita para todos os arquivos, pois o comando file pode não reconhecer o tipo de arquivo, mas funcionou bem para mim.

for f in *; do ext=$(file $f | awk '{print $2;}'); mv -n "$f" "$f.$ext"; done

O uso de awk é remover a segunda palavra da string retornada do arquivo de comando que é realmente a extensão.

Paolo
fonte
lida com jpg e png automaticamente. usei e funciona - muito obrigado! Só agora as extensões são CAPS. pequeno problema embora :)
krivar
0
rename --dry-run * -a ".jpg" # test  
* -a ".jpg" # rename
Roman Rhrn Nesterov
fonte
--dry-rune -anão estão disponíveis na minha versão de rename. Se for específico para alguma arquitetura, deve ser especificado.
Fernando César,
0

Você pode mover vários arquivos . Eu sou um mantenedor deste projeto. A sintaxe é simples.

mmf files*

Ele irá abrir seu $ EDITOR com todos os nomes de arquivos, ou vim por padrão e você pode simplesmente destacar o final de todos os nomes de arquivo usando Ctrl + v + G no vim, salvar o arquivo, sair e para que todos os seus arquivos sejam renomeados

Almas Abdrazak
fonte
-2

Ryan Li

A sintaxe correta para adicionar uma extensão de arquivo a vários arquivos dentro de um diretório que não tem uma extensão de arquivo é

find . | while read FILE; do if [[ -n `file --mime-type "$FILE" | grep 'message/rfc822'` ]]; then  mv "$FILE" "$FILE".eml; fi; done;
Dillon Beresford
fonte