Question

Je dois 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.

L’encodage qui m’intéresse est: ISO-8859-1. Si le codage est différent, je souhaite déplacer le fichier dans un autre répertoire.

Était-ce utile?

La solution

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

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

Autres conseils

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

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

Utilisation:

~> uchardet file.java 
UTF-8

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

voici un exemple de script utilisant le fichier -I et iconv qui fonctionne sur 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

Il est très 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 devrez utiliser un dictionnaire pour mieux deviner de quel mot il s'agit et déterminer ensuite quelle lettre il doit être. Enfin, si vous détectez que cela pourrait être utf-8, vous êtes sûr que ce n’est pas iso-8859-1

L’encodage est l’une des choses les plus difficiles à faire car vous ne savez jamais si rien ne vous dit

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

Dans Debian, vous pouvez également utiliser: encguess:

$ encguess test.txt
test.txt  US-ASCII

Ce n’est pas quelque chose que vous pouvez faire de manière infaillible. Une possibilité serait d’examiner chaque caractère du fichier pour s’assurer qu’il ne contient aucun caractère compris 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 la norme 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, trouvez l'équivalent des & "; et &"; "; &" mais des "!"; & "; &" en anglais! " of " et ainsi de suite dans toutes les langues prises en charge par 8859-1 et voyez si le fichier contient un grand nombre d'occurrences.

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 sait pas & "Et &"; Vous devrez probablement utiliser leur mot pour & "Le poisson " [désolé, c'est un peu stéréotypé, je ne voulais pas dire d'infraction, juste illustrer un point]).

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

Pour convertir le codage de 8859 en ASCII:

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

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

Sous 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

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, avec de très longues lignes

$ file -b sample.html

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

$ file -bi sample.html

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

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

utf-8

J'utilise le script suivant pour

  1. Trouvez tous les fichiers correspondant à FILTER avec SRC_ENCODING
  2. Créez 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 {} \;

Avec Perl, utilisez Encode :: Detect.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top