2 min read · 514 words
Se você travou em uma tarefa de substituição em lote de texto por causa do erro de "duplicate keys" em hashtables do PowerShell, este post é para você. Vou mostrar como contornei essa limitação de case-insensitivity do PowerShell para resolver o problema de forma rápida.
O Cenário
Eu precisava fazer um replace em lote de algumas strings de cores em hexadecimal dentro de um documento usando PowerShell. Para mapear os valores antigos para os novos, defini a seguinte hashtable com variações de maiúsculas e minúsculas:
$replacements = @{'#1e2a45'='#f6f7f8'; '#1E2A45'='#f6f7f8'}Mas assim que executei o script, ele quebrou logo na definição da hashtable.
O Erro: PowerShell hashtable duplicate keys
O erro exato que estourou no console foi o seguinte:
Duplicate keys '#1E2A45' are not allowed in hash literalsO motivo? Por padrão, o PowerShell é case-insensitive ao comparar chaves de hashtables. Por isso, ele enxerga #1e2a45 e #1E2A45 como a mesma chave, acusando duplicidade e lançando a exceção.
Ambiente
- SO: Windows
- Ferramenta: Windows PowerShell 5.1
- Stack: Hashtable literal (@{})
O que tentei e não funcionou
Minha primeira tentativa de contorno foi instanciar diretamente um objeto .NET usando New-Object System.Collections.Hashtable em vez da sintaxe literal (@{}). Mas deu na mesma: por baixo dos panos, o mecanismo de comparação continuou ignorando a diferença entre maiúsculas e minúsculas, resultando no mesmo erro.
Tentei de tudo para fazer o PowerShell respeitar o case, mas não teve jeito. Quando a ferramenta é teimosa, o melhor é não insistir no erro.
A Solução Definitiva
Em vez de ficar brigando com o PowerShell, decidi mudar de estratégia e usar Python, que é muito mais flexível para manipulação de texto. Usei o módulo re do Python com a flag re.I (case-insensitive) para compilar o padrão re.compile(re.escape(old), re.I). Com isso, consegui substituir todas as variações de hex de uma só vez e com total segurança.
O Código Utilizado
# Lista de substituições
swaps = [
('#1e2a45', '#f6f7f8'),
('#1E2A45', '#f6f7f8')
]
# Executa o replace ignorando case
for old, new in swaps:
pat = re.compile(re.escape(old), re.I)
content = pat.sub(new, content)Validação
Rodei o script em Python e ele processou com sucesso todas as 131 substituições de hexadecimais em uma única execução, sem nenhum erro de chave duplicada.
Status Atual
fixed (resolvido)
Dica para quem passar pelo mesmo
Se você está sofrendo com o erro de duplicate keys em hashtables do PowerShell, não perca tempo tentando criar dicionários complexos do .NET só para contornar isso. Se o seu objetivo é apenas fazer substituição de texto, mude para o Python usando a flag re.I. Sua produtividade (e saúde mental) agradecem.
Category Coverage Notice
This article follows our label-specific editorial criteria. Details: