Bagaimana cara mengetahui pengkodean bahasa dari nama file di Linux?

17

Saya memiliki direktori dengan ~ 10.000 file gambar dari sumber eksternal.

Banyak nama file berisi spasi dan tanda baca yang tidak ramah DB atau ramah Web. Saya juga ingin menambahkan nomor SKU di akhir setiap nama file (untuk tujuan akuntansi). Banyak, jika tidak sebagian besar nama file juga mengandung karakter latin yang diperluas yang ingin saya pertahankan untuk keperluan SEO (khususnya agar nama file secara akurat mewakili konten file dalam Gambar Google)

Saya telah membuat skrip bash yang mengubah nama (menyalin) semua file ke hasil yang saya inginkan. Skrip bash disimpan di UTF-8. Setelah menjalankannya menghapus sekitar 500 file (tidak dapat file stat ...).

Saya telah menjalankan convmv -f UTF-8 -t UTF-8 pada direktori, dan menemukan 500 nama file ini tidak dikodekan dalam UTF-8 (convmv dapat mendeteksi dan mengabaikan nama file yang sudah ada di UTF-8)

Apakah ada cara mudah saya bisa mengetahui mana encoding bahasa mereka sedang menggunakan?

Satu-satunya cara saya bisa mengetahui sendiri adalah dengan mengatur terminal saya encoding ke UTF-8, kemudian iterasi melalui semua kandidat kemungkinan pengkodean dengan convmv sampai menampilkan nama yang dikonversi yang 'terlihat benar'. Saya tidak punya cara untuk memastikan bahwa 500 file ini semua menggunakan pengkodean yang sama, jadi saya perlu mengulangi proses ini 500 kali. Saya ingin metode yang lebih otomatis daripada 'terlihat benar' !!!

rwired
sumber

Jawaban:

13

Tidak ada cara yang 100% akurat, tetapi ada cara untuk menebak dengan benar.

Ada chardet pustaka python yang tersedia di sini: https://pypi.python.org/pypi/chardet

misalnya

Lihat apa variabel LANG saat ini diatur ke:

$ echo $LANG
en_IE.UTF-8

Buat nama file yang harus dikodekan dengan UTF-8

$ touch mÉ.txt

Ubah pengkodean kami dan lihat apa yang terjadi ketika kami mencoba dan mendaftarnya

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

OK, jadi sekarang kita memiliki nama file yang dikodekan dalam UTF-8 dan lokal kita saat ini adalah C (standar halaman Unix).

Jadi mulailah python, impor chardet dan buat untuk membaca nama file. Saya menggunakan beberapa shell globbing (yaitu ekspansi melalui karakter * wildcard) untuk mendapatkan file saya. Ubah "ls m *" menjadi apa pun yang cocok dengan salah satu file contoh Anda.

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

Seperti yang Anda lihat, itu hanya tebakan. Seberapa baik tebakan ditunjukkan oleh variabel "kepercayaan".

Philip Reynolds
sumber
skrip berfungsi seperti yang dijelaskan, tetapi dalam kasus saya, chardet tidak menemukan penyandian file.
Fedir RYKHTIK
6

Anda mungkin menemukan ini berguna, untuk menguji direktori kerja saat ini (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'])

Hasilnya terlihat seperti:

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)

Untuk mengulang jalur melalui direktori saat ini, potong-dan-tempel ini menjadi skrip python kecil:

#!/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
sumber
Apakah itu bekerja dengan pengkodean Asia juga? Atau apakah itu Eurosentris?
rwired