Gostaria de renomear recursivamente todos os arquivos e pastas (subpastas) para maiúsculas.
Encontrei alguns scripts que o fazem em minúsculas, mas não sei como alterá-los, portanto, o fazemos de outra maneira (de baixo para cima).
O script que encontrei e funciona para letras minúsculas, mas não sabia como modificar é:
rename 'y/A-Z/a-z/' *
É de man rename
.
rename 'y/a-z/A-Z/' *
, conseguirá o que deseja. Cuidado onde você testá-lo.Respostas:
Note que você está usando o script Perl chamado
rename
distribuído pelo Debian e derivados (Ubuntu, Mint,…). Outras distribuições Linux oferecem um comando completamente diferente e consideravelmente menos útil chamadorename
.y/A-Z/a-z/
traduz cada personagem na faixaA
atravésZ
para o personagem correspondente na faixaa
atravész
, ou seja ASCII maiúsculas cartas para a letra minúscula correspondente. Para executar a tradução oposta, usey/a-z/A-Z/
. Outra maneira de escrever o mesmo comando érename '$_ = uc($_)' *
-uc
é a função u cper c ase, e orename
comando renomeia os arquivos com base na transformação feita na$_
variável.rename '…' *
renomeia apenas os arquivos no diretório atual, porque é isso que*
corresponde. Os arquivos de ponto (arquivos cujo nome começa com.
) também são ignorados.Se desejar renomear arquivos no diretório atual e nos subdiretórios recursivamente, você pode usar o
find
comando para percorrer o diretório atual recursivamente. Há uma dificuldade aqui: se você ligarrename
, isso renomeia o diretório e a parte do nome base. Se você chamarrename
um diretório antes de retornar a ele (find -exec rename … {} \;
),find
ficará confuso porque encontrou um diretório, mas esse diretório não existe mais no momento em que tenta descer para ele. Você pode contornar isso, dizendofind
que atravessar um diretório antes de agir sobre ele, mas depois você acaba tentando mudar o nomefoo/bar
paraFOO/BAR
mas o diretórioFOO
não existe.Uma maneira simples de evitar essa dificuldade é fazer com que o comando de renomeação atue apenas no nome base como parte do caminho. A expressão regular
([^/]*\Z)
corresponde à parte final do caminho que não contém a/
.O shell zsh fornece recursos mais convenientes para renomear - ainda mais enigmáticos que o Perl, mas mais tersos e geralmente mais fáceis de compor.
A função
zmv
renomeia arquivos com base em padrões. Executeautoload -U zmv
uma vez para ativá-lo (coloque esta linha na sua.zshrc
).No primeiro argumento para
zmv
(o padrão a ser substituído), você pode usar os poderosos padrões curinga do zsh . No segundo argumento parazmv
(o texto de substituição), você pode usar seus recursos de expansão de parâmetros , incluindo modificadores de histórico .Explicação:
-w
- atribuir variáveis numéricas automaticamente a cada padrão curinga**/*
- todos os arquivos em subdiretórios, recursivamente (**/
corresponde a 0, 1 ou mais níveis de subdiretórios)$1
- a primeira variável numérica, aqui correspondente à parte do diretório de cada caminho$2:u
- a segunda variável numérica, que corresponde aqui à parte do nome base de cada caminho, com o:u
modificador para converter o valor em maiúsculasComo um bônus adicional, isso respeita as configurações de local do ambiente.
Se você não tiver certeza sobre um
zmv
comando que escreveu, pode passar a-n
opção de imprimir o que o comando faria e não alterar nada. Verifique a saída e, se fizer o que deseja, execute novamente o comando sem-n
realmente agir.fonte
Roubado (com uma edição menor) do post de Gilles aqui
find <DIR> -depth -type d -exec rename -n 's!/([^/]*/?)$!\U/$1!' {} +
fonte
find <dir> -exec rename 'y/a-z/A-Z/' {} \;
find
está recorrendo a eles.find <dir> -depth -exec rename 'y/a-z/A-Z/' {} \;
deve lidar com o problema de renomear diretórios. Corrigir?rename
mudanças , por exemplo,foo/bar
paraFOO/BAR
eFOO
não existem nesse ponto.Gostaria de direcionar quem ainda está sendo vinculado a esta resposta à excelente resposta que Guiles Quernot deu a essa pergunta que não exige
find
.O comando resultante seria:
Mas antes de executar, leia a resposta vinculada a advertências sobre versões antigas do bash.
Finalmente, caso alguém esteja se perguntando o que o
y///
comando fazperl regex
. Aqui está um link para a documentação relevante .fonte
find -execdir
| renomearEssa seria a melhor maneira de fazer isso, se não fosse pela loucura relativa do caminho, pois evita que o Perl regex fu atue apenas no nome da base:
-execdir
primeirocd
s no diretório antes de executar apenas no nome da base.Infelizmente, não consigo me livrar dessa
PATH
parte de hackers,find -execdir
se recusa a fazer qualquer coisa se você tiver um caminho relativo emPATH
...: /ubuntu/621132/why-using-the-execdir-action- é inseguro para o diretório que está no caminho / 1109378 # 1109378fonte
Tente isso depois de mudar para o diretório em que você deseja renomear os arquivos:
fonte
ls -l
apenas para cortar as colunas que não sejam o nome?) E use aspas duplas em torno das substituições de variáveis . Seu código é excessivamente complexo e quebra nos nomes de arquivos que contêm espaços em branco e outros caracteres especiais. Usefind
ou**/
recursione em subdiretórios, a saída dels
é apenas para consumo humano.