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.
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 :)
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.
Usage:
~> 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 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
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.
Avec Python, vous pouvez utiliser le module chardet: https://github.com/chardet/chardet
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 .
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
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]).
Dans Debian, vous pouvez également utiliser: encguess
:
$ encguess test.txt
test.txt US-ASCII
Pour convertir le codage de 8859 en ASCII:
iconv -f ISO_8859-1 -t ASCII filename.txt
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
J'utilise le script suivant pour
.
#!/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 {} \;
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
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
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.