Como posso usar renomear para recursivamente renomear everyting para maiúsculas

5

Gostaria de renomear recursivamente todos os arquivos e pastas (subpastas) para maiúsculas.

Eu encontrei alguns scripts que farão isso em minúsculas, mas eu não sei como mudá-los, então ele fará o contrário (de baixo para cima).

O script que eu encontrei e funciona para minúsculas, mas eu não sabia como modificar é:

rename 'y/A-Z/a-z/' *

É de man rename .

    
por jnhghy - Alexandru Jantea 07.07.2014 / 09:11

3 respostas

5

Observe que você está usando o script Perl chamado rename distribuído por Debian e derivados (Ubuntu, Mint,…). Outras distribuições Linux enviam um comando completamente diferente e consideravelmente menos útil, chamado rename .

y/A-Z/a-z/ traduz cada caractere no intervalo A a Z no caractere correspondente no intervalo a a z , ou seja, letras maiúsculas ASCII para a letra minúscula correspondente. Para executar a tradução oposta, use y/a-z/A-Z/ . Outra forma de escrever o mesmo comando é rename '$_ = uc($_)' * - uc é a função u pper c ase, e o comando rename renomeia os arquivos com base na transformação feita para a variável $_ .

rename '…' * apenas renomeia arquivos no diretório atual, porque é isso que * corresponde. Os arquivos Dot (arquivos cujo nome começa com . ) também são ignorados.

Se você quiser renomear arquivos no diretório atual e em subdiretórios de forma recursiva, use o find comando para percorrer o diretório atual recursivamente. Há uma dificuldade aqui: se você chamar rename , isso renomeia tanto o diretório quanto a parte do nome base. Se você chamar rename em um diretório antes de recursar nele ( find -exec rename … {} \; ), find ficará confuso porque encontrou um diretório, mas esse diretório não existe mais no momento em que ele tenta descer nele. Você pode contornar isso dizendo find para percorrer um diretório antes de agir sobre ele, mas, em seguida, você acaba tentando renomear foo/bar para FOO/BAR , mas o diretório FOO não existe.

Uma maneira simples de evitar essa dificuldade é fazer com que o comando renomear atue apenas na parte do nome base do caminho. A expressão regular ([^/]*\Z) corresponde à parte final do caminho que não contém / .

find . -depth -exec rename 's!([^/]*\Z)!uc($1)!e' {} +

O shell zsh fornece recursos mais convenientes para renomear - ainda mais enigmático que o Perl, mas mais simples e mais fácil de compor .

A função zmv renomeia os arquivos com base em padrões. Execute autoload -U zmv uma vez para ativá-lo (coloque essa linha no seu .zshrc ).

No primeiro argumento para zmv (o padrão a ser substituído), você pode usar o poderoso padrões de curingas . No segundo argumento para zmv (o texto de substituição), você pode usar sua expansão de parâmetro recursos, incluindo modificadores de histórico .

zmv -w '**/*' '$1$2:u'

Explicação:

  • -w - automática atribui variáveis numéricas 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 correspondendo à parte do diretório de cada caminho
  • $2:u - a segunda variável numérica, aqui correspondendo a parte do nome base de cada caminho, com o modificador :u para converter o valor para maiúscula

Como um bônus adicional, isso respeita as configurações de localidade do ambiente.

Se você não tiver certeza sobre o comando zmv que escreveu, poderá passar a opção -n para imprimir o que o comando faria e não alterar nada. Verifique a saída e, se fizer o que você deseja, execute novamente o comando sem -n para realmente agir.

    
por 08.07.2014 / 02:06
4

Roubado (com uma pequena edição) de Gilles postar aqui

find <DIR> -depth -type d -exec rename -n 's!/([^/]*/?)$!\U/$1!' {} +

    
por 07.07.2014 / 09:24
0

Tente isso depois de se mudar para o diretório em que gostaria de renomear os arquivos:

for word in 'ls -ltr |tail -n +2 |awk '{print $9}''
do
  a=$(echo $word | tr '[a-z]' '[A-Z]')
  mv $word $a
  echo "Done Successfully"
done
    
por 07.07.2014 / 09:41