Jak rozpoznać kodowanie języka nazwy pliku w systemie Linux?

17

Mam katalog z ~ 10 000 plików obrazów z zewnętrznego źródła.

Wiele nazw plików zawiera spacje i znaki interpunkcyjne, które nie są przyjazne DB lub Web. Chcę również dołączyć numer SKU na końcu każdej nazwy pliku (do celów księgowych). Wiele, jeśli nie większość nazw plików, zawiera również rozszerzone znaki łacińskie, które chcę zachować dla celów SEO (szczególnie, aby nazwy plików dokładnie reprezentowały zawartość pliku w Grafice Google)

Zrobiłem skrypt bash, który zmienia nazwy (kopiuje) wszystkie pliki do pożądanego rezultatu. Skrypt bash jest zapisywany w UTF-8. Po uruchomieniu pomija około 500 plików (nie można zapisać pliku ...).

Uruchomiłem w katalogu convmv -f UTF-8 -t UTF-8 i odkryłem, że 500 nazw plików nie jest zakodowanych w UTF-8 (convmv jest w stanie wykryć i zignorować nazwy plików już w UTF-8)

Czy istnieje prosty sposób, aby dowiedzieć się, jakiego kodowania języka używają obecnie?

Jedynym sposobem, w jaki udało mi się to rozgryźć, jest ustawienie kodowania terminala na UTF-8, a następnie iterowanie wszystkich prawdopodobnych kodowań kandydujących za pomocą funkcji convmv, aż wyświetli się przekonwertowana nazwa, która „wygląda dobrze”. Nie mam pewności, że wszystkie te 500 plików używają tego samego kodowania, więc musiałbym powtórzyć ten proces 500 razy. Chciałbym bardziej zautomatyzowaną metodę niż „wygląda dobrze” !!!

okablowany
źródło

Odpowiedzi:

13

Tak naprawdę nie ma 100% dokładnego sposobu, ale istnieje sposób, aby zgadnąć.

Istnieje chardet biblioteki python, który jest dostępny tutaj: https://pypi.python.org/pypi/chardet

na przykład

Sprawdź, jaka jest bieżąca zmienna LANG:

$ echo $LANG
en_IE.UTF-8

Utwórz nazwę pliku, która będzie musiała zostać zakodowana za pomocą UTF-8

$ touch mÉ.txt

Zmień nasze kodowanie i zobacz, co się stanie, gdy spróbujemy je wymienić

$ ls m*
mÉ.txt
$ export LANG=C
$ ls m*
m??.txt

OK, więc teraz mamy nazwę pliku zakodowaną w UTF-8, a nasze obecne ustawienia regionalne to C (standardowa strona kodowa Uniksa).

Więc uruchom python, zaimportuj chardet i poproś, aby odczytał nazwę pliku. Używam globowania powłoki (tj. Interpretacji za pomocą znaku * z symbolem wieloznacznym), aby uzyskać mój plik. Zmień „ls m *” na cokolwiek, co pasuje do jednego z twoich przykładowych plików.

>>> import chardet
>>> import os
>>> chardet.detect(os.popen("ls m*").read())
{'confidence': 0.505, 'encoding': 'utf-8'}

Jak widać, to tylko przypuszczenie. Jak dobrze odgadnąć pokazuje zmienna „ufność”.

Philip Reynolds
źródło
skrypt działa zgodnie z opisem, ale w moim przypadku chardet nie znalazł kodowania pliku.
Fedir RYKHTIK
6

Przydatne może być przetestowanie bieżącego katalogu roboczego (python 2.7):

import chardet
import os  

for n in os.listdir('.'):
    print '%s => %s (%s)' % (n, chardet.detect(n)['encoding'], chardet.detect(n)['confidence'])

Wynik wygląda następująco:

Vorlagen => ascii (1.0)
examples.desktop => ascii (1.0)
Öffentlich => ISO-8859-2 (0.755682154041)
Videos => ascii (1.0)
.bash_history => ascii (1.0)
Arbeitsfläche => EUC-KR (0.99)

Aby ponownie wyświetlić ścieżkę koryta z bieżącego katalogu, wytnij i wklej to do małego skryptu python:

#!/usr/bin/python

import chardet
import os

for root, dirs, names in os.walk('.'):
    print root
    for n in names:
        print '%s => %s (%s)' % (n, chardet.detect(n)['encoding'], chardet.detect(n)['confidence'])
Klaus Kappel
źródło
Czy to też działa z kodowaniem azjatyckim? Czy jest to eurocentryczny?
połączono