Estou usando ccase .
O seguinte comando funciona.
$ mv camelCase (ccase -t Kebab camelCase)
Agora estou tentando renomear vários diretórios usando:
$ find . -type d -execdir rename 's/(.*)/$(ccase -t Kebab $1)/' '{}' \+
Isso não funciona, estou recebendo esta mensagem de erro:
Can't rename ./camelCase3 1000 4 24 27 30 46 121 132 1000ccase -t Kebab ./camelCase3): No such file or directory
O que posso fazer?
Deveria estar:
Nunca os incorpore
{}
no argumento de códigosh
de /bash
ou em qualquer interpretador de linguagem, isso o tornaria uma vulnerabilidade de injeção de comando. Veja É possível usar `find -exec sh -c` com segurança?Algumas outras notas:
-
, use o--
para marcar o fim das opções. Não sei seccase
suporta--
, se não, você pode relatar como um bug para seus mantenedores.bash
aqui, seu sistemash
deve ser suficientemv
, é uma boa ideia verificar se cada comando executado é bem-sucedido. Aqui usamos|| continue
para pular diretórios para os quaisccase
falha.+
em vez de;
passar vários diretórios parash
onde possível, o que evita ter que chamar um shell por arquivo. Nem todas asfind
implementações que oferecem suporte a esse predicado não padrão-execdir
farão isso. Em alguns, como em alguns BSDs ou versões mais antigas do GNUfind
,+
apenas faz o mesmo;
e o loop é redundante (embora inofensivo).mv -- SomeDir some_dir
, sesome_dir
já existe e é um diretório ou um link simbólico para um diretório, isso se torna o mesmo quemv -- SomeDir some_dir/SomeDir
. Com a implementação GNU demv
, isso pode ser evitado com a-T
opção (ou usezmv
conforme abaixo, que detectará o conflito)Para evitar isso
-execdir
e executar o menor número possível de shells, você pode usar,-exec
mas precisará separar o nome base e o diretório pai. Como melhoria, também podemos registrar falhas deccase
oumv
para que sejam refletidas nofind
status de saída de:Observe que acima estou adicionando um
-i
paramv
pelo menos dar ao usuário uma opção para evitar a perda de dados, como quando dois arquivos acabam tendo o mesmo novo nome. Uma abordagem melhor seria usar o zshzmv
, que pode verificar tudo com antecedência e possui um modo de simulação (-n
):Ele também omite arquivos ocultos por padrão. Ele faz uma travessia em profundidade por padrão. O
(#q/)
é o equivalente a-type d
. Nesse caso, o status de saída deccase
é ignorado. Quando o nome não é alterado, não há tentativa de renomeação.Você pode substituir
(*)
por(^*-*)
para evitar o processamento de arquivos que já possuem hífens em seus nomes.Você provavelmente também poderia fazer a conversão para o caso Kebab em zsh:
Onde convertemos todas as sequências de espaço em branco ou sublinhado em um único
-
, insira-
s entre caracteres não maiúsculos (exceto.
, e-
) e maiúsculos no nome base e converta todo o resultado eml
letras minúsculas. Você precisa se adaptar se quiserAFileInTheUK.txt
ser renomeadoa-file-in-the-u-k.txt
em vez deafile-in-the-uk.txt
.Renomeie os diretórios um por um e comece com o mais profundo primeiro. Por exemplo
Remova a palavra print para armar o script depois de verificar se ele faz o que você deseja ;-).
OP aqui. O comando que eu estava procurando é: