Alterar extensões de arquivo recursivamente no Bash

87

Quero recursivamente iterate através de um diretório e altere a extensão de todos os arquivos de uma determinada extensão, dizer .t1para .t2. Qual é o comando bash para fazer isso?

Amal Antony
fonte
14
imho, esta não é uma pergunta duplicada - a outra pergunta não é recursiva
usuário de linux shonky
Relacionado: askubuntu.com/questions/35922/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respostas:

207

Se você tiver renomear disponível, use:

find . -name "*.t1" -exec rename 's/\.t1$/.t2/' '{}' +

se não:

find . -name '*.t1' -exec rename .t1 .t2 {} +

Se renomear não estiver disponível, use:

find . -name "*.t1" -exec bash -c 'mv "$1" "${1%.t1}".t2' - '{}' +
anubhava
fonte
20
find . -name '*.t1' -exec rename .t1 .t2 {} +
Aaron Blenkush
2
(Minha versão do renamenão permite a expressão de substituição do estilo sed. Tenho que amar o Linux. Eu costumava ter que instalar o TotalCommander para Windows para fazer coisas assim.)
Aaron Blenkush
6
Caso alguém esteja se perguntando o que a "${1%.t1}".t2parte faz, como eu: Ela usa a manipulação de string bash para fazer o seguinte: 1 / Pegue o primeiro parâmetro posicional $1e trunque a .t1string literal de seu final ( %operador de sinal de porcentagem ). 2 / Anexe o .t2literal de string ao resultado.
Zack
2
A renomeação não funcionou para mim no OSX, mas a versão bash é incrível b / c acabei de adicionar 'git' na frente do mv e agora o git está feliz :-D
bdombro
3
preferir o usuário find . -type f -name '*.t1'para evitar pastas
Golak Sarangi
8

Se a sua versão do bashsuportar a globstaropção (versão 4 ou posterior):

shopt -s globstar
for f in **/*.t1; do
    mv "$f" "${f%.t1}.t2"
done 
chepner
fonte
7

Ou você pode simplesmente instalar o mmvcomando e fazer:

mmv '*.t1' '#1.t2'

Aqui #1está a primeira parte global, ou seja, o *in *.t1.

Ou no bash puro, uma maneira simples seria:

for f in *.t1; do
    mv "$f" "${i%.t1}.t2"
done

(ou seja: forpode listar arquivos sem a ajuda de um comando externo, como lsou find)

HTH

zmo
fonte
7
Presumo que o uso de "recursivamente" no OP se refere à renomeação de arquivos em subdiretórios do diretório também.
chepner de
Desculpe, mas qual é o significado de # 1?
inafalcao
1
é a primeira parte global, ou seja, o *in*.t1
zmo de
recursivamente: $ mmv -n ';*.t1' '#1#2.t2'. remover -nsinalizador para executar
okliv
5

Eu faria assim no bash:

for i in $(ls *.t1); 
do
    mv "$i" "${i%.t1}.t2" 
done

EDIT: meu erro: não é recursivo, aqui está minha maneira de mudar recursiva de nome de arquivo

for i in $(find `pwd` -name "*.t1"); 
do 
    mv "$i" "${i%.t1}.t2"
done
jrjc
fonte
8
Não analise ls e veja a mesma página para saber por que sua findsintaxe é ruim. Além disso, certifique-se de citar suas variáveis
Reintegrar Monica
2
Obrigado, eu não sabia.
jrjc