web-dev-qa-db-fra.com

Comment trouver le codage d'un fichier sous Unix via un ou plusieurs scripts

J'ai besoin de trouver le codage de tous les fichiers placés dans un répertoire. Est-il possible de trouver le codage utilisé?

La commande file n'est pas en mesure de le faire.

Le codage qui m’intéresse est: ISO-8859-1. Si l'encodage est autre chose, je veux déplacer le fichier dans un autre répertoire.

232
Manglu

On dirait que vous cherchez enca. Il peut deviner et même convertir entre les encodages. Il suffit de regarder la page de manuel .

Sinon, utilisez file -i (linux) ou file -I (osx). Cela produira des informations de type MIME pour le fichier, qui comprendront également le codage du jeu de caractères. J'ai trouvé un man-page pour cela aussi :)

333
Shalom Craimer
file -bi <file name>

Si vous aimez faire cela pour un tas de fichiers

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

uchardet - Une bibliothèque de détecteurs d’encodage portée depuis Mozilla.

Usage:

~> uchardet file.Java 
UTF-8

Diverses distributions Linux (Debian/Ubuntu, OpenSuse-packman, ...) fournissent des fichiers binaires.

27
qwert2003

voici un exemple de script utilisant le fichier -I et iconv qui fonctionne sous MacOsX Pour votre question, vous devez utiliser mv au lieu 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
8
Wolfgang Fahl

Il est vraiment difficile de déterminer s'il s'agit de l'iso-8859-1. Si vous avez un texte ne contenant que des caractères de 7 bits, il pourrait également s'agir d'iso-8859-1 mais vous ne le savez pas. Si vous avez des caractères de 8 bits, les caractères de la région supérieure existent également dans les codages d’ordre. Par conséquent, vous devriez utiliser un dictionnaire pour mieux deviner de quel mot il s'agit et déterminer à partir de là quelle lettre il doit être. Enfin si vous détectez que cela pourrait être utf-8 que vous êtes sûr que ce n’est pas iso-8859-1

Le codage est l’une des choses les plus difficiles à faire car on ne sait jamais si rien ne vous dit.

5
Norbert Hartl

Avec Python, vous pouvez utiliser le module chardet: https://github.com/chardet/chardet

2
fccoelho

Si vous parlez de fichiers XML (ISO-8859-1), la déclaration XML à l'intérieur spécifie le codage: <?xml version="1.0" encoding="ISO-8859-1" ?>
Ainsi, vous pouvez utiliser des expressions régulières (par exemple, avec Perl) pour vérifier chaque fichier pour une telle spécification.
Plus d'informations peuvent être trouvées ici: Comment déterminer le codage de fichier texte .

2
evgeny9

Je sais que vous souhaitez une réponse plus générale, mais ce qui est bien dans ASCII est généralement bon dans les autres codages. Voici une ligne unique Python permettant de déterminer si l’entrée standard est ASCII. (Je suis sûr que cela fonctionne en Python 2, mais je ne l'ai testé que sur 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
1
wkschwartz

Ce n'est pas quelque chose que vous pouvez faire d'une manière infaillible. Une possibilité serait d'examiner chaque caractère du fichier pour vous assurer qu'il ne contient aucun caractère dans les plages 0x00 - 0x1f ou 0x7f -0x9f, mais comme je l'ai dit, cela peut être vrai pour un nombre quelconque de fichiers, y compris au moins une autre variante de ISO8859.

Une autre possibilité est de rechercher des mots spécifiques dans le fichier dans toutes les langues prises en charge et de voir si vous pouvez les trouver.

Ainsi, par exemple, recherchez l'équivalent de l'anglais "et", "mais", "à", "de" et ainsi de suite dans toutes les langues prises en charge par 8859-1 et voyez si elles ont un grand nombre d'occurrences dans la liste. fichier.

Je ne parle pas de traduction littérale telle que:

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

bien que ce soit possible. Je parle de mots communs dans la langue cible (pour autant que je sache, l'islandais ne possède pas de mot pour "et" - vous devrez probablement utiliser leur mot pour "poisson" [désolé c'est un peu stéréotypé, je ne l'ai pas signifie toute infraction, illustrant juste un point]).

1
paxdiablo

Dans Debian, vous pouvez également utiliser: encguess:

$ encguess test.txt
test.txt  US-ASCII
1
not2qubit

Pour convertir le codage de 8859 en ASCII: 

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

Vous pouvez extraire le codage d'un seul fichier avec la commande de fichier. J'ai un fichier sample.html avec:

$ file sample.html 

sample.html: document HTML, texte Unicode UTF-8, très longues lignes

$ file -b sample.html

Document HTML, texte Unicode UTF-8, lignes très longues

$ file -bi sample.html

text/html; jeu de caractères = utf-8

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

utf-8

0
Daniel Faure

J'utilise le script suivant pour

  1. Trouver tous les fichiers qui correspondent à FILTER avec SRC_ENCODING
  2. Créer une sauvegarde d'eux
  3. Convertissez-les en DST_ENCODING
  4. (facultatif) Supprimer les sauvegardes

.

#!/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 {} \;
0
Matyas

En php, vous pouvez vérifier comme ci-dessous:

Spécifier explicitement la liste de codage:

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), 'UTF-8, ASCII, JIS, EUC-JP, SJIS, iso-8859-1') . PHP_EOL;"

"Mb_list_encodings" plus précis:

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), mb_list_encodings()) . PHP_EOL;"

Ici, dans le premier exemple, vous pouvez voir que je mets une liste de codages (détection de la liste) susceptibles de correspondre. Pour obtenir un résultat plus précis, vous pouvez utiliser tous les encodages possibles via: mb_list_encodings ()

Remarque les fonctions mb_ * nécessitent php-mbstring

apt-get install php-mbstring
0
Mohamed23gharbi

Dans Cygwin, cela semble fonctionner pour moi:

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

Exemple:

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

Vous pouvez diriger cela vers awk et créer une commande iconv pour tout convertir en utf8, à partir de tout codage source pris en charge par iconv.

Exemple:

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
0
skeetastax

avec cette commande:

for f in `find .`; do echo `file -i "$f"`; done

vous pouvez lister tous les fichiers dans un répertoire et des sous-répertoires et le codage correspondant.

0
danilo