Como limpar extensões de arquivo?

9

Eu tenho um diretório com arquivos .MP3 que gostaria de alterar as extensões para .mp3. Qual é a maneira mais fácil de fazer isso? Eu acho que algo como:

find /RootPath -type f -iname "*.mp3" -exec mv {} sed s/.*MP3/\1.mp3/ \; 

... embora eu saiba que isso não está certo. :) A substituição não está correta e não tenho certeza de como usar os comandos mva e a sedcom -execin find.

Eu precisaria de um script bash para isso?

Caleb
fonte

Respostas:

12

Aqui está uma maneira de fazer isso no Bash:

for i in *; do [ "${i/%MP3/mp3}" != "$i" ] && echo "$i" "${i/%MP3/mp3}"; done

Eu usei echoaqui para que o comando em si não faça nada, mas imprima pares de nomes de arquivos. Se essa lista representar as alterações que você deseja fazer, poderá mudar echopara algo como o mv -i --que moverá seus arquivos (e solicitará que você substitua).

Breve explicação:

Ele forrepete todos os arquivos correspondentes a *. Então, determinamos se a extensão já está em minúscula, se é que seguimos em frente, se não for, continuamos a movê-la (ou repetir, conforme o caso). Isso usa as operações de string incorporadas do Bash, sobre as quais você pode ler aqui: http://tldp.org/LDP/abs/html/string-manipulation.html

Steven D
fonte
Obrigado pela sua resposta e apontando-me para um link sobre manipulação de string bash!
7

No zsh:

autoload zmv
zmv '(*).MP3' '$1.mp3'   # rename files in the current directory only
zmv '(**/)(*).MP3' '$1$2.mp3'  # rename files in subdirectories as well

Para também cuidar de .Mp3ou .mP3arquivos:

zmv '(**/)(*).(#i)mp3' '$1$2.mp3'
Gilles 'SO- parar de ser mau'
fonte
6

Você pode usar o comando rename (cuidado, existem duas implementações principais com APIs diferentes) para elas. Por exemplo, para alterar o caso das extensões de nome de arquivo de cima para baixo, tente o seguinte:

  • com renamefrom util-linux(às vezes chamado rename.ul), supondo que .JPGocorra apenas uma vez nos nomes dos arquivos

    rename -- .JPG .jpg *.JPG
  • com o renamefrom perl(às vezes chamado prename; várias variantes foram publicadas):

    rename 's/\.JPG$/.jpg/' ./*.JPG

Aqui está um tutorial de alguns caras sobre como ele mudou de um script bash confuso para esse comando simples para exatamente o seu caso de uso.

Outro comando sofisticado para fazer isso é pax. Se você estiver usando o ZSH para seu shell, também poderá usar zmv.

Caleb
fonte
super! exatamente o que eu precisava
JoshP
Eu recebo um erro syntax error at (user-supplied code), near "."quando executo este comando.
Ryan Gates
3

Use perl-rename , canivete suíço de renomeação de arquivos com expressões regulares (no ubuntu, isso é fornecido com o pacote perl como nome de usuário):

# Replace prename as appropriate (i.e. if you've got it installed under a different name
find /RootPath -type f -iname '*.mp3' -print0 | xargs -0 prename 's/mp3$/mp3/i'

Se você for cuidadoso, use as opções -n e -v para renomear o perl e ver o que ele realmente fará.

Kjetil Jorgensen
fonte
Obrigado pela sua resposta. Não tem perlrename no servidor, mas vou brincar com ele mais tarde hoje!
0

Você precisa de um script, porque "extensões" no Linux são na verdade apenas partes da sequência do nome do arquivo. Você precisa fazer alguma manipulação de string no script para obter o novo nome.

#!/bin/bash
for NAME in *.JPG
do
    PREFIX=${NAME%.*}
    NEWNAME="$PREFIX.jpg"
    mv "$NAME" "$NEWNAME"
done

A citação dupla é importante se você tiver nomes de arquivos com espaços em branco. Eu pensei que algumas das aspas duplas eram um pouco óbvias.

Bruce Ediger
fonte
1
Não há nada errado com o seu script, mas você desafiadoramente não precisa de um script para isso. Provavelmente, há uma dúzia de maneiras de fazer isso em uma linha na maioria dos shells, e muitos utilitários para facilitar também.
Caleb
0

Na festança:

# renaming files in the current directory only
for f in *.MP3; do mv "$f" "${f%.MP3}.mp3"; done  

# renaming files in subdirectories as well
for f in *{,/*}.mp3; do mv "$f" "${f%.MP3}.mp3"; done
Maxime R.
fonte
0

primeiro faça backup de seus arquivos! você pode usar um liner python:

python -c "import glob,os; [os.rename(fn, fn.replace('.MP3', '.mp3')) for fn in glob.glob('PATH_TO_YOUR_DIRECTORY')]"

EDITAR:

Aqui está uma explicação detalhada de como o one-liner realmente funciona. Usando python -cestamos passando um comando para o interpretador python. Depois de importar as bibliotecas ospara a renamefunção e globpara a listagem de arquivos, precisamos percorrer a lista de arquivos no diretório fornecido, que eu chamei PATH_TO_YOUR_DIRECTORY, por exemplo, algo como ./*tudo no diretório atual.

Infelizmente, na sintaxe de uma linha, os forloops não funcionam após a importnotação, portanto, precisamos usar a notação entre colchetes. Ou seja, para cada nome de arquivo ou diretório que globestá nos dando do caminho especificado, no formato de uma string, substituímos * .MP3 por * .mp3.

Como o OP não mencionou a pesquisa recursiva, eu não a incluí em primeiro lugar.

xaratustra
fonte