Ich habe ein lang laufendes Python-Skript, das eine Datei nicht in UTF-8 dekodieren konnte. Die Fehlermeldung sagt mir nicht, bei welcher Datei der Fehler aufgetreten ist, sondern nur, dass das Byte 0x81
an Position nicht dekodiert werden konnte 194
. Ich weiß, in welchem Ordner sich die Datei befindet, aber nicht, wo unter den Tausenden von Dateien irgendwo in diesem Unterbaum. Welche Möglichkeiten habe ich, diese Datei (und andere wie sie) zu finden? Gibt es dafür einen schönen Einzeiler in Bash?
Das Skript so zu ändern, dass es ausgibt, was es anzeigt, und es dann erneut auszuführen, wobei jeweils eine Datei nach der anderen repariert wird, ist kaum eine Option, da das einmalige Ausführen des Skripts viele Stunden dauert. Einen Directory-Traverser in Python zu schreiben, scheint mir ein bisschen zu viel Arbeit zu sein.
Antwort1
Verwendung isutf8
aus dem moreutils
Paket:
find . -name '*.py' -exec isutf8 {} +
Oder:
find . -name '*.py' | xargs isutf8
(Letzteres unter der Annahme, dass die Dateinamen keine Zeilenumbrüche haben.)
Antwort2
Um eine ähnlich fehlgeschlagene Datei zu erstellen, können wir dieses Skript verwenden:
{ printf '%*s' "179"; printf '\x81'; printf '%*s' "20"; } >infile
Anschließend gibt dieser Befehl aus, an welcher Stelle die Datei fehlschlägt:
$ isutf8 infile
infile: line 1, char 1, byte offset 180: invalid UTF-8 code
Dies prüft alle python( .py
)-Dateien im pwd auf einen ungültigen Code an Position 180:
$ isutf8 ./*.py | grep "offset 180"
Oder noch flexibler, ein Bereich von Offsets (erweiterter regulärer Ausdruck von GNU):
$ isutf8 ./*.py | grep -E "offset (17|18)"
Oder ein spezifischer Test für Dateien im gesamten Verzeichnis:
$ find . -iname "*.py" -type f -exec bash -c 'isutf8 "$1" | grep -E "offset (17|18)"' Find {} \;