Como localizar / substituir caracteres em um nome de pasta?

0

Eu quero realizar as seguintes operações:

  • Localize / substitua (usando regexp) todas as ocorrências de <>:"\|? e substitua-as por uma string vazia
  • Localize / substitua (usando regexp) todas as ocorrências de ^\.+|\.+$ e substitua-as por uma string vazia

Como teste, criei manualmente duas pastas (veja a captura de tela) e as executei:

find "/home/users/Downloads/test" -regextype sed -regex "*<>:\|?*" -type d
find "/Users/chiyo/Downloads/test" -regextype sed -regex "*[<>:\|?]*" -type d
find "/Users/chiyo/Downloads/test" -regextype sed -regex "[<>:\|?]" -type d

e não encontrou nenhum.

Estou usando esta versão do find .

=> find --version
find (GNU findutils) 4.6.0
Copyright (C) 2015 Free Software Foundation, Inc.

Alguma idéia de como isso pode ser feito?

    
por mrjayviper 02.07.2018 / 16:27

2 respostas

4

Os dois primeiros exemplos estão fora.

  • *<>:\|?* Você não pode começar com * . * significa 0 ou mais do átomo anterior. Ele também diz < seguido por > seguido por : … e ? é um caractere especial.
  • *[<>:\|?]* Esta é mais perto que você está usando uma classe de personagem, mas ainda o * no início.
  • [<>:\|?] Isso corresponderia se fosse uma correspondência de sub-regex, mas não é. Você precisa combinar o nome do arquivo inteiro, incluindo o caminho do diretório.

Portanto, adicione códigos regex para consumir coisas antes e depois. ( . é qualquer caractere, * é zero ou mais garantias do átomo anterior. Portanto, .* corresponderá a qualquer coisa.)

Portanto, tente .*[<>:\|?].*

Você não vai substituir nada assim, e você não nos disse o que quer que seja substituído por ele.

    
por 02.07.2018 / 20:04
3

Use -name em vez de -regex (já que são os nomes de arquivos em que você está realmente interessado e -regex corresponde ao caminho completo):

find folder -type d -name '*[<>:\|?]*'

Isso localizaria qualquer diretório no ou abaixo de folder cujo nome contenha pelo menos um dos caracteres < , > , : , \ , | ou ? .

Para remover esses caracteres dos nomes dos diretórios:

find folder -depth -type d -name '*[<>:\|?]*' \
    -execdir bash -c 'mv "$1" "${1//[<>:\|?]/}"' bash {} ';'

Isso pressupõe que o novo nome de um diretório renomeado já não seja o nome de um diretório existente. Adicionando um teste para confrontos de nomes:

find folder -depth -type d -name '*[<>:\|?]*' \
    -execdir bash -c '[ ! -e "${1//[<>:\|?]/}" ] && mv "$1" "${1//[<>:\|?]/}"' bash {} ';'

Isso evitaria tentar renomear um diretório se o novo nome já existir

O comando mv é executado em um shell filho bash . O shell é executado com o diretório pai do diretório encontrado como seu diretório de trabalho. Ele está usando uma substituição de parâmetro bash -specific para excluir todos os caracteres ofensivos dos nomes de arquivos dos diretórios encontrados.

O comando também usa -depth para fazer um primeiro percurso de profundidade da estrutura de diretórios em folder . Sem isso, find tentaria entrar em diretórios que você acabou de renomear e falhará.

Relacionados:

por 03.07.2018 / 08:59