¿LC_ALL=C es destructivo?

¿LC_ALL=C es destructivo?

Tengo un conjunto de archivos de texto razonablemente grande (~15 GB). Estos archivos son esencialmente bases de datos simples que contienen credenciales, y las credenciales que contienen a menudo se encuentran fuera del rango ASCII de 128 caracteres (caracteres acentuados y similares).

Cuando intento ordenar algunos de estos archivos con:

sort -u input.txt -o output.txt

...Obtuve el siguiente error:

sort: string comparison failed: Invalid or incomplete multibyte or wide character
sort: Set LC_ALL='C' to work around the problem.

He leído mucho sobre cómo el uso LC_ALL=Cpuede acelerar los comandos que tratan con caracteres, como sorty grep, incluidosLa brillante respuesta de Stéphane Chazelassobre el tema, pero me preocupan específicamente las implicaciones de usarlo en mi conjunto de datos.

¿Es probable que la ejecución LC_ALL=C sort -ude estos archivos les quite cualquier carácter que no sea ASCII?

Si esto es, entonces, ¿qué puedo hacer para arreglar/eliminar todo?caracteres anchos o multibyte no válidos o incompletos" de estos archivos, lo que me permite ordenarlos sin utilizar LC_ALL=C?

Respuesta1

¿Es probable que la ejecución de LC_ALL=C sort -u en estos archivos les quite cualquier carácter que no sea ASCII?

En este caso no, no; sortsimplemente trabajará directamente en los valores de bytes en lugar de intentar convertirlos en caracteres.

Sin embargo, no ocurre necesariamente lo mismo con otras herramientas. Los programas escritos en C (el lenguaje) son los que tienen más probabilidades de comportarse de esta manera. Los programas escritos en lenguajes con una fuerte distinción entre bytes y caracteres, como en Python 3, deberían negarse rotundamente a aceptar entradas que no se ajusten al conjunto de caracteres. Y ciertamente puedo imaginar programas mal escritos que ignoran los errores y generan ?en su lugar una � o una.

Si es así, entonces, ¿qué puedo hacer para arreglar/eliminar todos los "caracteres anchos o multibyte no válidos o incompletos" de estos archivos, permitiéndome ordenarlos sin usar LC_ALL=C?

Asegúrese de que todos estén usando la misma codificación de archivo (preferiblemente UTF-8) y de que su configuración regional esté usando la misma codificación. El error nunca debería ocurrir para un archivo UTF-8 válido, sin importar cuán grande sea.

Respuesta2

Debido a que terminé necesitando canalizar mis archivos a través de muchas herramientas Bash diferentes como , , y sort, grepdecidí awkque era más seguro buscar la "solución adecuada" indicada en la respuesta aceptada; convirtiéndolos todos a UTF-8 primero. Esto terminó siendo un poco más difícil de lo esperado, sobre todo porque me tomó un tiempo darme cuenta de que no es confiable para determinar si un archivo es ASCII o UTF-8 (porque no verifica la totalidad del archivo). así que dejo esta respuesta aquí para la posteridad.wctrfile

Para determinar definitivamente en qué codificación están sus archivos, primero asegúrese de que el uchardetpaquete esté instalado a través del instalador de Cygwin oapt-cyg, entonces corre:

uchardet *.txt

O si no estás en Cygwin:

chardet *.txt 

Mueva todos los archivos que chardetaparecen en la lista ASCIIa una carpeta propia y ejecute el siguiente forbucle en esa carpeta:

for i in *.txt; do iconv -f ASCII -t UTF-8 "$i" >> "${i%.txt}_utf.txt"; done;

Recorrerá todos .txtlos archivos de una carpeta y creará versiones UTF-8 de ellos con el utfsufijo agregado.

Al volver a ejecutarlo uchardet *.txt, es posible que aún se muestren algunos archivos como ASCII. Esto sucede porque ASCII es un subconjunto de UTF-8 ysimplemente significaque esos archivos no contengan caracteres fuera del rango ASCII de 128 bits.

Ahora debería poder ejecutar sortsin necesidad de utilizar LC_ALL=C.

información relacionada