AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 749699
Accepted
Ahmad Ismail
Ahmad Ismail
Asked: 2023-06-24 06:49:51 +0800 CST2023-06-24 06:49:51 +0800 CST 2023-06-24 06:49:51 +0800 CST

Renomeie várias pastas usando a ferramenta de manipulação de string externa

  • 772

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?

command-line
  • 3 3 respostas
  • 36 Views

3 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2023-06-24T16:53:58+08:002023-06-24T16:53:58+08:00

    Deveria estar:

    find . -depth ! -name . -type d -execdir sh -c '
      for dir do
        dir=${dir#*/} # remove the ./ prefix that some find implementations add
        new_dir=$(ccase -t Kebab -- "$dir") || continue
        [ "$dir" = "$new_dir" ] ||
          mv -i -- "$dir" "$new_dir"
      done' sh {} +
    

    Nunca os incorpore {}no argumento de códigosh de / bashou 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:

    • quando você não pode garantir que os dados da variável não comecem com um -, use o --para marcar o fim das opções. Não sei se ccasesuporta --, se não, você pode relatar como um bug para seus mantenedores.
    • não há necessidade bashaqui, seu sistema shdeve ser suficiente
    • em sh como em bash, as expansões de parâmetros e as substituições de comandos devem ser citadas quando no contexto da lista, pelo menos, ou caso contrário, elas passam por split+glob! Veja, por exemplo, as implicações de segurança de esquecer de citar uma variável em bash/POSIX shells
    • Especialmente ao fazer algo potencialmente destrutivo, como chamar mv, é uma boa ideia verificar se cada comando executado é bem-sucedido. Aqui usamos || continuepara pular diretórios para os quais ccasefalha.
    • observe o +em vez de ;passar vários diretórios para shonde possível, o que evita ter que chamar um shell por arquivo. Nem todas as findimplementações que oferecem suporte a esse predicado não padrão -execdirfarão isso. Em alguns, como em alguns BSDs ou versões mais antigas do GNU find, +apenas faz o mesmo ;e o loop é redundante (embora inofensivo).
    • cuidado que em mv -- SomeDir some_dir, se some_dirjá existe e é um diretório ou um link simbólico para um diretório, isso se torna o mesmo que mv -- SomeDir some_dir/SomeDir. Com a implementação GNU de mv, isso pode ser evitado com a -Topção (ou use zmvconforme abaixo, que detectará o conflito)

    Para evitar isso -execdir e executar o menor número possível de shells, você pode usar, -execmas precisará separar o nome base e o diretório pai. Como melhoria, também podemos registrar falhas de ccaseou mvpara que sejam refletidas no findstatus de saída de:

    find . -depth ! -name . -type d -exec sh -c '
      ret=0
      for dir do
        base=${base##*/}
        parent=${dir%/*}
        new_base=$(ccase -t Kebab -- "$base") && {
          [ "$base" = "$new_base" ] ||
            mv -i -- "$dir" "$parent/$new_base"
        } || ret=$?
      done
      exit "$ret"' sh {} +
    

    Observe que acima estou adicionando um -ipara mvpelo 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 zsh zmv, que pode verificar tudo com antecedência e possui um modo de simulação ( -n):

    autoload -Uz zmv
    zmv -n '(**/)(*)(#q/)' '$1$(ccase -t Kebab -- $2)'
    

    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 de ccaseé 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:

    zmv -n '(**/)(*)(#q/)' \
           '$1${${${2//[_[:space:]]##/-}//(#b)([^[:upper:].-])([[:upper:]])/$match[1]-$match[2]}:l}'
    

    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 em lletras minúsculas. Você precisa se adaptar se quiser AFileInTheUK.txtser renomeado a-file-in-the-u-k.txtem vez de afile-in-the-uk.txt.

    • 3
  2. jelmd
    2023-06-24T11:36:08+08:002023-06-24T11:36:08+08:00

    Renomeie os diretórios um por um e comece com o mais profundo primeiro. Por exemplo

    #!/bin/ksh93
    
    find . -type d -depth -print | while read DIR ; do
        PREFIX=${DIR%/*}
        SUFFIX=${ ccase -t Kebab "${.sh.match:1}"; }
        print mv "${DIR}" "${PREFIX}/${SUFFIX}"
    done
    

    Remova a palavra print para armar o script depois de verificar se ele faz o que você deseja ;-).

    • 0
  3. Ahmad Ismail
    2023-06-24T16:25:37+08:002023-06-24T16:25:37+08:00

    OP aqui. O comando que eu estava procurando é:

    find . -depth -type d -execdir bash -c 'mv {} $(ccase -t Kebab {})' \;
    
    • 0

relate perguntas

  • O comando ip suporta curingas?

  • Qual é a interface recomendada para um utilitário que requer muitos parâmetros? [fechado]

  • Execute o aplicativo X remotamente, execute a GUI no host remoto [fechado]

  • Fazendo mysql CLI me pedir uma senha interativamente

  • Pub / sub de linha de comando sem um servidor?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve