Encontre arquivos por codificação de caracteres

Encontre arquivos por codificação de caracteres

Eu tenho um script python de longa execução que não conseguiu decodificar um arquivo em utf-8. A mensagem de erro não informa em qual arquivo ocorreu a falha, apenas que não foi possível decodificar byte 0x81em position 194. Eu sei em qual pasta o arquivo está, mas não onde entre os milhares de arquivos em algum lugar dessa subárvore. Quais são minhas opções para encontrar este arquivo (e outros semelhantes)? Existe uma linha bonita no bash para isso?

Alterar o script para imprimir o que ele está vendo e executá-lo novamente, corrigindo um arquivo por vez, dificilmente é uma opção, pois executar o script uma vez leva muitas horas. Escrever um atravessador de diretório em Python parece trabalhoso demais.

Responder1

Usando isutf8do moreutilspacote:

find . -name '*.py' -exec isutf8 {} +

Ou:

find . -name '*.py' | xargs isutf8

(Último, assumindo que os nomes dos arquivos não possuem novas linhas.)

Responder2

Para construir um arquivo com falha semelhante, podemos usar este script:

{ printf '%*s' "179"; printf '\x81'; printf '%*s' "20"; } >infile

Então este comando imprimirá em qual posição o arquivo falhou:

$ isutf8 infile 
infile: line 1, char 1, byte offset 180: invalid UTF-8 code

Portanto, isso testará todos .pyos arquivos python() no pwd em busca de um código inválido na posição 180:

$ isutf8 ./*.py | grep "offset 180"

Ou ainda mais flexível, uma série de compensações (gnu Extended Regex):

$ isutf8 ./*.py | grep -E "offset (17|18)"

Ou um teste específico para arquivos dentro de todo o diretório:

$ find . -iname "*.py" -type f -exec bash -c 'isutf8 "$1" | grep -E "offset (17|18)"' Find {} \;

informação relacionada