Renomeie para Start Case ou Initial Caps no Bash

3

Eu preciso de um oneliner para renomear todos os arquivos em um diretório de

SomeThing.TXT
NOT A FILE.ogg
sensitive lalala.doc

para

Something.txt
Not A File.ogg
Sensitive Lalala.doc

Em outras palavras: as primeiras letras de palavras são maiúsculas e tudo o mais é minúsculo. Isso é chamado de Iniciar caso ou limites iniciais . Está muito perto de "Título do caso". A extensão do arquivo deve estar em minúsculas.

A maioria das questões existentes parece lidar apenas com nomes de arquivos UPPERCASE.MKV ou lowercase.mkv , nenhum parece cobrir Capitalized Case.mkv ( exemplo ).

Todas as ferramentas comuns, como pipes, sed , perl , grep e mais podem ser usadas.

    
por qubodup 30.07.2015 / 13:49

4 respostas

1

Eu criei uma solução rápida no formato de uma linha:

for f in *; do mv -i "$f" "'echo $f | sed -e 's/\(.*\)/\L/' -e 's/\( .\)/\U/g' -e 's/\(^.\)/\U/g''"; done

Ou em legível (mas marginalmente menos confortável para copiar o formulário de colagem):

for f in *; do 
    mv -i "$f" "'echo $f | 
     sed -e 's/\(.*\)/\L/' -e 's/\( .\)/\U/g' -e 's/\(^.\)/\U/g''"; 
done

Esse comando usa sed to mv each file para um arquivo com o mesmo nome, mas no qual todos os caracteres são os primeiros convertido para minúsculas , então cada combinação de espaço seguida por qualquer caractere é transformada em maiúscula, então o primeiro caractere é virado em maiúsculas.

Isso perguntará antes de sobrescrever.

Remova -i se você quiser substituí-lo automaticamente.

    
por 30.07.2015 / 14:08
2

Se você tiver acesso a renomear perl, (instalado por padrão como rename em sistemas baseados no Debian, disponível como perl-rename em muitos outros), você pode executar:

rename  's/.*/lc($&)/e; s/(^| )./uc($&)/ge' *

Explicação:

O programa rename executará uma expressão perl em cada um de seus nomes de arquivos de entrada. Aqui, a primeira operação de substituição ( s/// ) substituirá tudo ( .* ) por ela mesma ( $& é o que foi correspondido), mas menor é maiúscula ( lc($&) ). O segundo, irá corresponder a todos os caracteres que estão após um espaço ou no início do nome do arquivo ( (^| ) ) e substituí-lo com sua versão maiúscula ( uc($&) ).

Execute o sinalizador -n para testar sem fazer alterações:

$ rename -n 's/.*/lc($&)/e; s/ ./uc($&)/ge' *
rename NOT A FILE.ogg not A File.ogg
rename sensitive lalala.doc sensitive Lalala.doc
rename SomeThing.TXT something.txt

Você também pode usar um loop de shell e perl:

for f in *; do 
    mv "$f" "$(perl -lpe 's/.*/lc($&)/e; s/(^| )./uc($&)/ge' <<<"$f")"
done

Este é o mesmo comando que no rename acima, apenas nós o alimentamos em cada arquivo no diretório e usamos substituição de comando para renomear.

Você pode modificar isso facilmente para evitar a substituição de arquivos existentes:

for f in *; do 
    target="$(perl -lpe 's/.*/lc($&)/e; s/(^| )./uc($&)/ge' <<<"$f")"; 
    [ -e "$target" ] && 
        echo "File \"$target\" exists, skipping \"$f\"" || 
        mv "$f" "$target"; 
done
    
por 30.07.2015 / 14:08
1

"Eliminação de maiúsculas" respondeu aqui :

for i in *
do
  mv "$i" "$( echo $i | tr '[:upper:]' '[:lower:]')"
done

Capitalizando já respondidas aqui :

for i in *
do
  mv "$i" "$( echo $i | sed 's/[ ]*/\u&/g')"
done
    
por 30.07.2015 / 14:08
1

Isso funciona em Bash 3.2.57 para Mac OSX

Visualizar (não altera nada):

IFS=$'\n';FOLDER=new;for F in $(ls -1);do EXT="${F##*.}";NAME="${F%.*}";NEW=$(echo "$NAME"| perl -pe 's/[ _-]([A-z0-9])([^ _-]+)/ \U\L/g');echo "cp '$F' '$FOLDER/$NEW.$EXT'";done

Se a visualização parece boa, você pode usar isso para renomear e cp em subpasta:

IFS=$'\n';FOLDER=new;[ -d $FOLDER ] || mkdir $FOLDER;for F in $(ls -1);do EXT="${F##*.}";NAME="${F%.*}";NEW=$(echo "$NAME"| perl -pe 's/[ _-]([A-z0-9])([^ _-]+)/ \U\L/g');cp -v "$F" "$FOLDER/$NEW.$EXT";done

Notas:

  • Não alterará a extensão do arquivo.
  • Deve manipular números corretamente.
  • Se você tiver outros caracteres que deseja converter em espaços, basta adicioná-los à classe de caracteres: [ _-]
  • Evita nomes conflitantes, fazendo uma cópia de cada arquivo em uma subpasta. Isso lhe dá uma opção "desfazer". Outra maneira de lidar com isso seria renomear todos os arquivos, adicionando um prefixo como _My New File Name.jpg e renomear todos eles para versões sem o _ .
por 30.07.2015 / 14:49