Comment trouver l'encodage d'un fichier sous Unix via le script(s)
je dois trouver le codage de tous les fichiers qui sont placés dans un répertoire. Est-il un moyen de trouver l'encodage utilisé?
la commande file
ne peut pas faire cela.
l'encodage qui m'intéresse est:ISO-8859-1. Si l'encodage est autre chose, je veux déplacer le fichier vers un autre répertoire.
14 réponses
sonne comme si vous cherchiez enca
. Il peut deviner et même convertir entre les encodages. Il suffit de regarder la man page .
ou, à défaut, utilisez file -i
(linux) ou file -I
(osx). Cela produira des informations de type MIME pour le fichier, qui inclura également l'encodage des caractères. J'ai trouvé un l'homme-page pour elle, trop :)
file -bi <file name>
Si vous voulez faire cela pour un tas de fichiers
for f in `find | egrep -v Eliminate`; do echo "$f" ' -- ' `file -bi "$f"` ; done
voici un exemple de script utilisant file-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 vraiment difficile de déterminer si c'est iso-8859-1. Si vous avez un texte avec seulement 7 caractères bit qui pourrait aussi être iso-8859-1 mais vous ne savez pas. Si vous avez des caractères de 8 bits, alors les caractères de la région supérieure existent aussi dans l'ordre des encodages. Par conséquent, vous devez utiliser un dictionnaire pour obtenir une meilleure estimation de ce mot et de déterminer à partir de là quelle lettre il doit être. Enfin, si vous détectez qu'il pourrait être en utf-8 que vous êtes sûr qu'il n'est pas iso-8859-1
encodage est l'une des choses les plus difficiles à faire parce que vous ne savez jamais si rien ne vous dit
si vous parlez de fichiers XML (ISO-8859-1), la déclaration XML à l'intérieur d'eux spécifie l'encodage: <?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.
Pour plus d'informations, cliquez ici: Comment déterminer L'encodage D'un fichier texte .
avec Python, vous pouvez utiliser le module chardet: https://github.com/chardet/chardet
ce n'est pas quelque chose que vous pouvez faire d'une manière infaillible. Une possibilité serait d'examiner chaque caractère dans le fichier pour s'assurer qu'il ne contient pas de caractères dans les gammes 0x00 - 0x1f
ou 0x7f -0x9f
mais, comme je l'ai dit, cela peut être vrai pour n'importe quel nombre de fichiers, y compris au moins une autre variante de ISO8859.
une Autre possibilité est de chercher des mots spécifiques dans le fichier, dans toutes les langues prises en charge et voir si vous pouvez les trouver.
Ainsi, par exemple, trouver l'équivalent de l'anglais "et", "mais", "", "" et ainsi de suite dans toutes les langues prises en charge de 8859-1 et voir si ils ont un grand nombre d'occurrences dans le fichier.
Je ne parle pas de traduction littérale comme:
English French
------- ------
of de, du
and et
the le, la, les
bien que ce soit possible. Je parle de mots courants dans la langue cible (pour autant que je sache, Islandais n'a pas de mot pour "et" - vous auriez probablement à utiliser leur mot pour "poisson" [désolé c'est un peu stéréotypé, Je ne voulais pas offenser, juste illustrer un point]).
je sais que vous êtes intéressé par une réponse plus générale, mais ce qui est bon en ASCII est généralement bon dans d'autres encodages. Voici un one-liner Python pour déterminer si l'entrée standard est ASCII. (Je suis presque 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
Dans Cygwin, il semble que ça fonctionne 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 pipe cela à awk et créer une commande iconv pour tout convertir en utf8, à partir de n'importe quel encodage source supporté par iconv.
exemple:
find -type f -name "*.txt" | while read file; do (file -i "$file"); done | awk -F[:=] '{print "iconv -f "" -t utf8 \"""\" > \"""_utf8\""}' | bash
dans Debian vous pouvez aussi utiliser: encguess
:
$ encguess test.txt
test.txt US-ASCII
Vous pouvez extraire l'encodage d'un seul fichier avec la commande file. J'ai un échantillon.fichier html avec:
$ file sample.html
de l'échantillon.html: document HTML, texte Unicode UTF-8, avec de très longues lignes
$ file -b sample.html
document HTML, UTF-8 texte Unicode ,avec de très longues lignes
$ file -bi sample.html
text / html; charset=utf-8
$ file -bi sample.html | awk -F'=' '{print }'
utf-8
j'utilise le script suivant pour
- trouver tous les fichiers qui correspondent à FILTER with SRC_ENCODING
- Créer une sauvegarde
- Convertissez-les en DST_ENCODING
- (optionnel) 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 {} \;