Ich muss die Kodierung aller Dateien finden, die in einem Verzeichnis abgelegt werden. Gibt es eine Möglichkeit, die verwendete Kodierung zu finden?
Der Befehl file
ist dazu nicht in der Lage.
Die Kodierung, die mich interessiert, ist: ISO-8859-1. Wenn die Kodierung etwas anderes ist, möchte ich die Datei in ein anderes Verzeichnis verschieben.
Klingt wie Sie nach enca
suchen. Es kann zwischen Kodierungen raten und sogar konvertieren. Schauen Sie sich einfach die man-Seite an.
Andernfalls verwenden Sie file -i
(linux) oder file -I
(osx). Dadurch werden MIME-Typinformationen für die Datei ausgegeben, die auch die Zeichensatzkodierung enthalten. Ich habe eine man-Seite auch dafür gefunden :)
file -bi <file name>
Wenn Sie dies für eine Reihe von Dateien tun möchten
for f in `find | egrep -v Eliminate`; do echo "$f" ' -- ' `file -bi "$f"` ; done
uchardet - Eine von Mozilla portierte Codierungsdetektor-Bibliothek.
Verwendungszweck:
~> uchardet file.Java
UTF-8
Verschiedene Linux-Distributionen (Debian/Ubuntu, OpenSuse-packman, ...) bieten Binärdateien.
hier ist ein Beispielskript mit Datei -I und Iconv, das unter MacOsX .__ funktioniert. Für Ihre Frage müssen Sie mv anstelle von iconv verwenden
#!/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
Es ist wirklich schwer festzustellen, ob es sich um iso-8859-1 handelt. Wenn Sie einen Text mit nur 7-Bit-Zeichen haben, könnte dies auch iso-8859-1 sein, wissen Sie aber nicht. Wenn Sie 8-Bit-Zeichen haben, sind die Zeichen der oberen Region auch in der Reihenfolge der Kodierung vorhanden. Dazu müssten Sie ein Wörterbuch verwenden, um besser zu erraten, um welches Wort es sich handelt, und bestimmen Sie dann, um welchen Buchstaben es sich handelt. Wenn Sie schließlich feststellen, dass es sich um utf-8 handelt, sind Sie sicher, dass es nicht iso-8859-1 ist
Das Kodieren ist eine der schwierigsten Aufgaben, da Sie nie wissen, ob Ihnen nichts gesagt wird
Mit Python können Sie das Chardet-Modul verwenden: https://github.com/chardet/chardet
Wenn Sie über XML-Dateien (ISO-8859-1) sprechen, gibt die darin enthaltene XML-Deklaration die Kodierung an: <?xml version="1.0" encoding="ISO-8859-1" ?>
Sie können also reguläre Ausdrücke (z. B. mit Perl
) verwenden, um jede Datei auf eine solche Spezifikation zu überprüfen.
Weitere Informationen finden Sie hier: So bestimmen Sie die Kodierung von Textdateien .
Ich weiß, dass Sie an einer allgemeineren Antwort interessiert sind, aber was in ASCII gut ist, ist normalerweise auch in anderen Kodierungen gut. Hier ist ein Python-Einzeiler, um zu bestimmen, ob die Standardeingabe ASCII ist. (Ich bin mir ziemlich sicher, dass dies in Python 2 funktioniert, aber ich habe es nur auf Python 3 getestet.)
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
Dies ist nicht etwas, das Sie auf eine narrensichere Weise tun können. Eine Möglichkeit wäre, jedes Zeichen in der Datei zu überprüfen, um sicherzustellen, dass es keine Zeichen in den Bereichen 0x00 - 0x1f
oder 0x7f -0x9f
enthält. Dies kann jedoch, wie gesagt, für eine beliebige Anzahl von Dateien zutreffen, einschließlich mindestens einer anderen Variante von ISO8859.
Eine andere Möglichkeit besteht darin, nach bestimmten Wörtern in der Datei in allen unterstützten Sprachen zu suchen und zu sehen, ob Sie sie finden können.
Finden Sie zum Beispiel das Äquivalent des Englischen "und", "aber", "bis", "von" usw. in allen unterstützten Sprachen von 8859-1, und prüfen Sie, ob sie eine große Anzahl von Vorkommen innerhalb von Datei.
Ich spreche nicht von wörtlicher Übersetzung wie:
English French
------- ------
of de, du
and et
the le, la, les
obwohl das möglich ist. Ich spreche von gebräuchlichen Wörtern in der Zielsprache (für alles was ich weiß, hat Isländisch kein Wort für "und" - Sie müssten wahrscheinlich ihr Wort für "Fisch" verwenden [Entschuldigung, das ist ein bisschen stereotypisch, das habe ich nicht.) jede Beleidigung bedeuten, nur einen Punkt veranschaulichen]).
In Debian können Sie auch Folgendes verwenden: encguess
:
$ encguess test.txt
test.txt US-ASCII
So konvertieren Sie die Kodierung von 8859 in ASCII:
iconv -f ISO_8859-1 -t ASCII filename.txt
Sie können die Codierung einer einzelnen Datei mit dem Dateibefehl extrahieren. Ich habe eine sample.html-Datei mit:
$ file sample.html
sample.html: HTML-Dokument, UTF-8-Unicode-Text mit sehr langen Zeilen
$ file -b sample.html
HTML-Dokument, UTF-8-Unicode-Text, mit sehr langen Zeilen
$ file -bi sample.html
text/HTML; Zeichensatz = utf-8
$ file -bi sample.html | awk -F'=' '{print $2 }'
utf-8
Ich verwende das folgende Skript um
.
#!/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 {} \;
In PHP können Sie wie folgt überprüfen:
Codierungsliste explizit angeben:
php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), 'UTF-8, ASCII, JIS, EUC-JP, SJIS, iso-8859-1') . PHP_EOL;"
Genauere "mb_list_encodings":
php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), mb_list_encodings()) . PHP_EOL;"
Hier im ersten Beispiel können Sie sehen, dass ich eine Liste von Codierungen (Erkennungslistenreihenfolge) erstellt habe, die möglicherweise übereinstimmen. Um genauere Ergebnisse zu erhalten, können Sie alle möglichen Kodierungen verwenden: mb_list_encodings ()
Hinweis Für mb_ * -Funktionen ist php-mbstring erforderlich
apt-get install php-mbstring
In Cygwin sieht das so aus, als würde es für mich funktionieren:
find -type f -name "<FILENAME_GLOB>" | while read <VAR>; do (file -i "$<VAR>"); done
Beispiel:
find -type f -name "*.txt" | while read file; do (file -i "$file"); done
Sie können dies an awk weiterleiten und einen iconv-Befehl erstellen, um alles von einer beliebigen von iconv unterstützten Quellcodierung in utf8 zu konvertieren.
Beispiel:
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
mit diesem Befehl:
for f in `find .`; do echo `file -i "$f"`; done
sie können alle Dateien in einem Verzeichnis und Unterverzeichnissen sowie die entsprechende Codierung auflisten.