Pregunta

Necesito encontrar la codificación de todos los archivos que se colocan en un directorio. ¿Hay alguna forma de encontrar la codificación utilizada?

El comando file no puede hacer esto.

La codificación que me interesa es: ISO-8859-1. Si la codificación es otra cosa, quiero mover el archivo a otro directorio.

¿Fue útil?

Solución

Parece que estás buscando enca. Puede adivinar e incluso convertir entre codificaciones. Solo mire la página del manual .

O, en su defecto, use file -i (linux) o file -I (osx). Eso generará información de tipo MIME para el archivo, que también incluirá la codificación del juego de caracteres. Encontré una página de manual para ello también :)

Otros consejos

file -bi <file name>

Si desea hacer esto para un montón de archivos

for f in `find | egrep -v Eliminate`; do echo "$f" ' -- ' `file -bi "$f"` ; done

uchardet : una biblioteca de detectores de codificación portada desde Mozilla.

Uso:

~> uchardet file.java 
UTF-8

Varias distribuciones de Linux (Debian / Ubuntu, OpenSuse-packman, ...) proporcionan binarios.

aquí hay un script de ejemplo que usa el archivo -I e iconv que funciona en MacOsX Para su pregunta, debe usar mv en lugar de iconv

#!/bin/bash
# 2016-02-08
# check encoding and convert files
for f in *.java
do
  encoding=`file -I $f | cut -f 2 -d";" | cut -f 2 -d=`
  case $encoding in
    iso-8859-1)
    iconv -f iso8859-1 -t utf-8 $f > $f.utf8
    mv $f.utf8 $f
    ;;
  esac
done

Es realmente difícil determinar si es iso-8859-1. Si tiene un texto con solo caracteres de 7 bits que también podría ser iso-8859-1 pero no lo sabe. Si tiene caracteres de 8 bits, los caracteres de la región superior también existen en codificaciones de orden. Por lo tanto, tendría que usar un diccionario para adivinar mejor qué palabra es y determinar a partir de ahí qué letra debe ser. Finalmente, si detecta que puede ser utf-8, entonces está seguro de que no es iso-8859-1

La codificación es una de las cosas más difíciles de hacer porque nunca se sabe si nada te dice

Con Python, puede usar el módulo chardet: https://github.com/chardet/chardet

En Debian también puede usar: encguess:

$ encguess test.txt
test.txt  US-ASCII

Esto no es algo que puedas hacer de una manera infalible. Una posibilidad sería examinar cada carácter en el archivo para asegurarse de que no contenga ningún carácter en los rangos 0x00 - 0x1f o 0x7f -0x9f pero, como dije, esto puede ser cierto para cualquier número de archivos, incluido al menos otra variante de ISO8859.

Otra posibilidad es buscar palabras específicas en el archivo en todos los idiomas admitidos y ver si puede encontrarlas.

Entonces, por ejemplo, encuentre el equivalente del inglés " y " ;, " pero " ;, " a " ;, " de " y así sucesivamente en todos los idiomas admitidos de 8859-1 y ver si tienen una gran cantidad de ocurrencias dentro del archivo.

No estoy hablando de traducción literal como:

English   French
-------   ------
of        de, du
and       et
the       le, la, les

aunque eso es posible. Estoy hablando de palabras comunes en el idioma de destino (por lo que sé, islandés no tiene palabra para & Quot; y & Quot; - probablemente tendría que usar su palabra para & Quot; fish " [lo siento, es un poco estereotipado, no quise decir ninguna ofensa, solo ilustrando un punto]).

Si está hablando de archivos XML (ISO-8859-1), la declaración XML dentro de ellos especifica la codificación: <?xml version="1.0" encoding="ISO-8859-1" ?>
Por lo tanto, puede usar expresiones regulares (por ejemplo, con perl) para verificar cada archivo para dicha especificación.
Puede encontrar más información aquí: Cómo determinar la codificación de archivos de texto .

Para convertir la codificación de 8859 a ASCII:

iconv -f ISO_8859-1 -t ASCII filename.txt

Sé que está interesado en una respuesta más general, pero lo que es bueno en ASCII generalmente es bueno en otras codificaciones. Aquí hay una línea única de Python para determinar si la entrada estándar es ASCII. (Estoy bastante seguro de que esto funciona en Python 2, pero solo lo he probado en Python 3.)

python -c 'from sys import exit,stdin;exit()if 128>max(c for l in open(stdin.fileno(),"b") for c in l) else exit("Not ASCII")' < myfile.txt

En Cygwin, parece que funciona para mí:

find -type f -name "<FILENAME_GLOB>" | while read <VAR>; do (file -i "$<VAR>"); done

Ejemplo:

find -type f -name "*.txt" | while read file; do (file -i "$file"); done

Puede canalizar eso a awk y crear un comando iconv para convertir todo a utf8, desde cualquier codificación de fuente compatible con iconv.

Ejemplo:

find -type f -name "*.txt" | while read file; do (file -i "$file"); done | awk -F[:=] '{print "iconv -f "$3" -t utf8 \""$1"\" > \""$1"_utf8\""}' | bash

Puede extraer la codificación de un solo archivo con el comando de archivo. Tengo un archivo sample.html con:

$ file sample.html 

sample.html: documento HTML, texto UTF-8 Unicode, con líneas muy largas

$ file -b sample.html

Documento HTML, texto Unicode UTF-8, con líneas muy largas

$ file -bi sample.html

texto / html; charset = utf-8

$ file -bi sample.html  | awk -F'=' '{print $2 }'

utf-8

Estoy usando el siguiente script para

  1. Encuentra todos los archivos que coinciden con FILTER con SRC_ENCODING
  2. Crear una copia de seguridad de ellos
  3. Conviértalos a DST_ENCODING
  4. (opcional) Eliminar las copias de seguridad

.

#!/bin/bash -xe

SRC_ENCODING="iso-8859-1"
DST_ENCODING="utf-8"
FILTER="*.java"

echo "Find all files that match the encoding $SRC_ENCODING and filter $FILTER"
FOUND_FILES=$(find . -iname "$FILTER" -exec file -i {} \; | grep "$SRC_ENCODING" | grep -Eo '^.*\.java')

for FILE in $FOUND_FILES ; do
    ORIGINAL_FILE="$FILE.$SRC_ENCODING.bkp"
    echo "Backup original file to $ORIGINAL_FILE"
    mv "$FILE" "$ORIGINAL_FILE"

    echo "converting $FILE from $SRC_ENCODING to $DST_ENCODING"
    iconv -f "$SRC_ENCODING" -t "$DST_ENCODING" "$ORIGINAL_FILE" -o "$FILE"
done

echo "Deleting backups"
find . -iname "*.$SRC_ENCODING.bkp" -exec rm {} \;

Con Perl, use Encode :: Detect.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top