unknown - ubuntu change encoding file
Cómo encontrar la codificación de un archivo en Unix a través de script(s) (14)
Necesito encontrar la codificación de todos los archivos que se colocan en un directorio. ¿Hay alguna manera de encontrar la codificación utilizada?
El comando de 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.
Aquí hay un script de ejemplo que usa el archivo -I y iconv que funciona en MacOsX. Para su pregunta, necesita 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
Con Perl, use Encode :: Detect.
Con Python, puede usar el módulo chardet: https://github.com/chardet/chardet
En Cygwin, esto 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 origen admitida por 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
En Debian también puedes usar: encguess
:
$ encguess test.txt
test.txt US-ASCII
Es realmente difícil determinar si es iso-8859-1. Si tiene un texto con solo 7 bits de caracteres, 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 orden codificaciones. Por lo tanto, tendría que usar un diccionario para obtener una mejor idea de qué palabra es y determinar a partir de qué letra debe ser. Finalmente, si detecta que puede ser más de 8 que de seguro, 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 está diciendo.
Esto no es algo que puedas hacer de manera infalible. Una posibilidad sería examinar cada carácter del 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, incluyendo al menos Otra variante de ISO8859.
Otra posibilidad es buscar palabras específicas en el archivo en todos los idiomas compatibles y ver si puede encontrarlas.
Entonces, por ejemplo, encuentre el equivalente de inglés "and", "but", "to", "of" y así sucesivamente en todos los idiomas admitidos de 8859-1 y vea si tienen una gran cantidad de incidencias dentro del expediente.
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é, el islandés no tiene una palabra para "y", es probable que tenga que usar su palabra para "pescado" [lo siento, es un poco estereotipado, no lo hice significa cualquier ofensa, simplemente ilustrando un punto]).
Estoy usando el siguiente script para
- Encuentra todos los archivos que coinciden con FILTER con SRC_ENCODING
- Crea una copia de seguridad de ellos.
- Convertirlos a DST_ENCODING
- (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 {} /;
Puede extraer la codificación de un solo archivo con el comando file. 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 UTF-8 Unicode, con líneas muy largas.
$ file -bi sample.html
texto / html; conjunto de caracteres = utf-8
$ file -bi sample.html | awk -F''='' ''{print $2 }''
utf-8
Sé que está interesado en una respuesta más general, pero lo que es bueno en ASCII es generalmente bueno en otras codificaciones. Aquí hay una línea 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
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 tal especificación.
Puede encontrar más información aquí: Cómo determinar la codificación de archivos de texto .
Suena como si estuvieras buscando enca
. Puede adivinar e incluso convertir entre codificaciones. Solo mira la página del manual .
O, en su defecto, use el file -i
(linux) o el file -I
(osx). Eso generará información de tipo MIME para el archivo, que también incluirá la codificación del conjunto de caracteres. También encontré una man-page de man-page para ello :)
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.
file -bi <file name>
Si te gusta hacer esto para un montón de archivos
for f in `find | egrep -v Eliminate`; do echo "$f" '' -- '' `file -bi "$f"` ; done