Bagaimana cara menentukan pengodean file di OS X?

171

Saya mencoba memasukkan beberapa karakter UTF-8 ke dalam file LaTeX di TextMate (yang mengatakan pengkodean defaultnya adalah UTF-8), tetapi LaTeX tampaknya tidak memahaminya.

Running cat my_file.texmenunjukkan karakter dengan benar di Terminal. Running ls -almenunjukkan sesuatu yang belum pernah saya lihat sebelumnya: "@" oleh daftar file:

-rw-r--r--@  1 me      users      2021 Feb 11 18:05 my_file.tex

(Dan, ya, saya menggunakan \usepackage[utf8]{inputenc}di LaTeX.)

Saya telah menemukan iconv, tetapi itu tampaknya tidak dapat memberi tahu saya apa pengkodeannya - itu hanya akan dikonversi setelah saya mengetahuinya.

James A. Rosen
sumber
Dalam pengalaman saya, perintah file (1) selalu cukup bagus untuk menebak penyandian file. Saya tidak tahu apakah itu cukup pintar untuk menggunakan atribut file com.apple.TextEncoding yang diperluas atau tidak.
Edward Falk

Jawaban:

33

The @berarti bahwa file tersebut memiliki file diperpanjang atribut yang terkait dengan itu. Anda dapat meminta mereka menggunakan getxattr()fungsi.

Tidak ada cara pasti untuk mendeteksi penyandian file. Baca jawaban ini , itu menjelaskan mengapa.

Ada alat baris perintah, enca , yang mencoba menebak penyandian. Anda mungkin ingin memeriksanya.

codelogic
sumber
1
Saya berasumsi bahwa OSX menyimpan encoding sebagai meta-data. Saya mengerti isi file hanya sekelompok bit dan tidak memiliki encoding yang melekat.
James A. Rosen
1
@ JamesA.Pilih aplikasi OS X seperti TextEdit menyimpan penyandian file sebagai atribut (bernama "com.apple.TextEncoding"). Sangat mungkin bahwa atribut yang ditunjukkan oleh itu @termasuk atribut pengkodean file. Anda dapat menggunakan perintah xattr -p com.apple.TextEncoding <filename>untuk melihat atribut penyandian jika ada.
bames53
1
dapatkah Anda menjelaskan cara menggunakan getxattr? Saya tidak bisa menggunakannya.
MeV
1
Itu adalah panggilan fungsi yang akan Anda gunakan jika Anda ingin menulis sebuah program. Dari baris perintah, cukup ketik ls -l@ <filename>untuk melihat atribut apa yang ditetapkan untuk file tersebut. Untuk melihat atribut yang sebenarnya, ketikxattr -p com.apple.TextEncoding <filename>
Edward Falk
Untuk encamelakukan brew install encadan Anda harus menentukan bahasa tetapi tidak ada yang berhasil, jadi:enca FILENAME -L __
Shane
434

Menggunakan opsi -I(itu huruf kapital i) pada perintah file tampaknya menunjukkan penyandian file.

file -I {filename}
Tim
sumber
58
Saya perlu menggunakan -I
Casebash
7
Fungsi ini tampaknya tidak dapat membedakan antara ASCII dan UTF-8 (Tampaknya mereka sama untuk sebagian besar karakter AS, tetapi tidak semua, mungkin sesuatu yang akan mendeteksi bit unicode)
BadPirate
14
ASCII dan UTF8 sama kecuali ada karakter di luar OxFF dalam file, atau BOM.
davidtbernal
3
file -I *tampaknya berfungsi dengan baik untuk saya (di OSX). Suatu sistem mengeluhkan penyandian salah satu dari banyak file, tanpa menentukan yang mana. Semua file ascii, kecuali satu, yang utf-8. Kemungkinan besar pelakunya.
mcv
1
@ notJim Itu tidak benar. ASCII hanya didefinisikan melalui 0x7F sehingga apa pun di luar titik itu jelas bukan ASCII. Unicode dan Latin-1 memiliki poin kode yang sama dalam 0x80-0xFF tetapi tidak ada pengkodean umum Unicode yang identik dengan Latin-1 (karena itu secara inheren akan dibatasi hingga 8 bit, yang terlalu sedikit untuk Unicode).
tripleee
56

Di Mac OS X perintah file -I(huruf kapital i) akan memberi Anda set karakter yang tepat selama file yang Anda uji mengandung karakter di luar kisaran ASCII dasar.

Misalnya jika Anda masuk ke Terminal dan menggunakan vi untuk membuat file misalnya. vi test.txt kemudian masukkan beberapa karakter dan sertakan karakter beraksen (coba ALT-e diikuti oleh e) kemudian simpan file.

Mereka mengetik file -I text.txtdan Anda akan mendapatkan hasil seperti ini:

test.txt: text/plain; charset=utf-8

Cloudranger
sumber
3
Saya dapat mengkonfirmasi kasus OS X, charset = us-ascii atau charset = utf-8 tergantung pada konten file
Ben
tetapi sepertinya hanya melihat beberapa KB pertama dari file tersebut. dalam kasus saya, perintah vim di stackoverflow.com/a/33644535/161022 dengan benar mengidentifikasi file sebagai utf-8 sedangkan fileperintah mengklaim ituus-ascii
lmsurprenant
Memang, tampak bahwa file curang karena alasan kinerja. Saya baru saja membuat file ASCII 3MB di Ubuntu dan menambahkan beberapa karakter UTF-8 sampai akhir dan masih melaporkan ASCII bukan UTF-8. Saya mencoba opsi -k (teruskan) tetapi kemudian melaporkan "data" bukan "UTF-8" jadi masih tidak bagus.
Cloudranger
24
vim -c 'execute "silent !echo " . &fileencoding | q' {filename}

alias di suatu tempat dalam konfigurasi bash saya sebagai

alias vic="vim -c 'execute \"silent !echo \" . &fileencoding | q'"

jadi saya ketik saja

vic {filename}

Pada vanilla OSX Yosemite saya, ini menghasilkan hasil yang lebih tepat daripada "file -I":

$ file -I pdfs/udocument0.pdf
pdfs/udocument0.pdf: application/pdf; charset=binary
$ vic pdfs/udocument0.pdf
latin1
$
$ file -I pdfs/t0.pdf
pdfs/t0.pdf: application/pdf; charset=us-ascii
$ vic pdfs/t0.pdf
utf-8
jmettraux
sumber
1
Ini adalah satu-satunya jawaban yang memberi saya apa yang saya butuhkan - "latin1", bukan "us-ascii". Meskipun, saya memang harus menghapus garis miring terbalik.
katy lavallee
Terima kasih banyak, saya menghapus garis miring terbalik.
jmettraux
21

Anda juga dapat mengonversi dari satu jenis file ke yang lain menggunakan perintah berikut:

iconv -f original_charset -t new_charset originalfile > newfile

misalnya

iconv -f utf-16le -t utf-8 file1.txt > file2.txt
RPM
sumber
13

Cukup gunakan:

file -I <filename>

Itu dia.

bx2
sumber
2
Saya tidak dapat diganggu untuk memberikan suara, tetapi jawaban itu sepenuhnya salah. Small -i mengatakan jangan mengklasifikasikan konten jika itu adalah file biasa. -Saya setara dengan --mime yang menampilkan string tipe mime. Alat osx berperilaku berbeda dari alat linux standar.
sillyMunky
Nah, untuk file yang disandikan Windows 125 file -Imembuat saya text/plain; charset=unknown-8bit. Meskipun bekerja lebih baik untuk file utf8: text/plain; charset=utf-8.
MiB
8

Menggunakan fileperintah dengan --mime-encodingopsi (misal file --mime-encoding some_file.txt) sebagai ganti opsi -I bekerja pada OS X dan memiliki manfaat tambahan dengan menghilangkan tipe mime, "text / plain", yang mungkin tidak Anda pedulikan.

Adam
sumber
ls -l @ a akan menampilkan atribut yang diperluas . Melihat halaman manual untuk ls di Yosemite, saya tidak melihat opsi --mime-encoding.
rstackhouse
Anda berbicara tentang fileperintah itu. Tidak tahu kalau ada. Cupu. Bagaimanapun. Maaf tentang downvote. JADI tidak akan membiarkan saya membatalkannya kecuali seseorang mengedit jawaban ini.
rstackhouse
4

Classic 8-bit LaTeX sangat terbatas di mana karakter UTF8 dapat digunakan; itu sangat tergantung pada pengkodean font yang Anda gunakan dan mesin terbang mana font yang telah tersedia.

Karena Anda tidak memberikan contoh spesifik, sulit untuk mengetahui dengan tepat di mana masalahnya - apakah Anda mencoba menggunakan mesin terbang yang tidak dimiliki font Anda atau apakah Anda tidak menggunakan pengkodean font yang benar di awal tempat.

Berikut adalah contoh minimal yang menunjukkan bagaimana beberapa karakter UTF8 dapat digunakan dalam dokumen LaTeX:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\begin{document}
‘Héllø—thêrè.’
\end{document}

Anda mungkin lebih beruntung dengan pengkodean [utf8x], tetapi sedikit diperingatkan bahwa itu tidak lagi didukung dan memiliki beberapa keistimewaan dibandingkan dengan [utf8] (sejauh yang saya ingat; sudah lama saya tidak melihatnya). Tetapi jika itu berhasil, itulah yang terpenting bagi Anda.

Will Robertson
sumber
3

Tanda @ berarti file tersebut memiliki atribut yang diperluas . xattr filemenunjukkan atribut apa yang dimilikinya, xattr -l filemenunjukkan nilai atribut juga (yang kadang-kadang bisa besar - coba misalnya xattr /System/Library/Fonts/HelveLTMMuntuk melihat font gaya lama yang ada di fork sumber daya).

Jouni K. Seppänen
sumber
2

Mengetik file myfile.texdi terminal kadang-kadang bisa memberi tahu Anda pengkodean dan jenis file menggunakan serangkaian algoritma dan angka ajaib. Ini cukup berguna tetapi jangan mengandalkan itu memberikan informasi konkret atau dapat diandalkan.

Sebuah Localizable.stringsberkas (ditemukan dalam aplikasi lokal Mac OS X) biasanya dilaporkan menjadi UTF-16 C file sumber.

dreamlax
sumber
1

Synalyze It! memungkinkan untuk membandingkan teks atau byte di semua penyandian yang ditawarkan perpustakaan ICU . Dengan menggunakan fitur itu, Anda biasanya langsung melihat halaman kode mana yang masuk akal untuk data Anda.

pi3
sumber
1

Anda dapat mencoba memuat file ke jendela firefox kemudian pergi ke View - Character Encoding. Harus ada tanda centang di sebelah jenis penyandian file.

jmdeamer
sumber
0

LaTeX mana yang Anda gunakan? Ketika saya menggunakan teTeX, saya harus mengunduh paket unicode secara manual dan menambahkannya ke file .tex saya:

% UTF-8 stuff
\usepackage[notipa]{ucs}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}

Sekarang, saya telah beralih ke XeTeX dari paket TeXlive 2008 (di sini ), bahkan lebih sederhana:

% UTF-8 stuff
\usepackage{fontspec}
\usepackage{xunicode}

Sedangkan untuk mendeteksi penyandian file, Anda bisa bermain file(1)(tapi agak terbatas) tetapi seperti kata orang lain, itu sulit.

Keltia
sumber
0

Cara kasar untuk memeriksa enkode mungkin hanya dengan memeriksa file dalam hex editor atau sejenisnya. (atau tulis program untuk memeriksa) Lihatlah data biner dalam file. Format UTF-8 cukup mudah dikenali. Semua karakter ASCII adalah byte tunggal dengan nilai di bawah 128 (0x80) Urutan multibyte mengikuti pola yang ditunjukkan dalam artikel wiki

Jika Anda dapat menemukan cara yang lebih sederhana untuk mendapatkan program untuk memverifikasi pengkodean untuk Anda, itu jelas jalan pintas, tetapi jika semuanya gagal, ini akan melakukan trik.

jalf
sumber
0

Saya menerapkan skrip bash di bawah, ini berfungsi untuk saya.

Pertama kali mencoba iconvdari pengkodean yang dikembalikan oleh file --mime-encodingke utf-8.

Jika gagal, ia akan melewati semua penyandian dan menunjukkan perbedaan antara file asli dan yang disandikan ulang. Itu melompati pengkodean yang menghasilkan keluaran diff besar ("besar" seperti yang didefinisikan oleh MAX_DIFF_LINESvariabel atau argumen input kedua), karena mereka kemungkinan besar pengkodean yang salah.

Jika "hal buruk" terjadi akibat menggunakan skrip ini, jangan salahkan saya. Ada rm -fdi sana, jadi ada monster. Saya mencoba untuk mencegah efek buruk dengan menggunakannya pada file dengan akhiran acak, tetapi saya tidak membuat janji.

Diuji pada Darwin 15.6.0.

#!/bin/bash

if [[ $# -lt 1 ]]
then
  echo "ERROR: need one input argument: file of which the enconding is to be detected."
  exit 3
fi

if [ ! -e "$1" ]
then
  echo "ERROR: cannot find file '$1'"
  exit 3
fi

if [[ $# -ge 2 ]]
then
  MAX_DIFF_LINES=$2
else
  MAX_DIFF_LINES=10
fi


#try the easy way
ENCOD=$(file --mime-encoding $1 | awk '{print $2}')
#check if this enconding is valid
iconv -f $ENCOD -t utf-8 $1 &> /dev/null
if [ $? -eq 0 ]
then
  echo $ENCOD
  exit 0
fi

#hard way, need the user to visually check the difference between the original and re-encoded files
for i in $(iconv -l | awk '{print $1}')
do
  SINK=$1.$i.$RANDOM
  iconv -f $i -t utf-8 $1 2> /dev/null > $SINK
  if [ $? -eq 0 ]
  then
    DIFF=$(diff $1 $SINK)
    if [ ! -z "$DIFF" ] && [ $(echo "$DIFF" | wc -l) -le $MAX_DIFF_LINES ]
    then
      echo "===== $i ====="
      echo "$DIFF"
      echo "Does that make sense [N/y]"
      read $ANSWER
      if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ]
      then
        echo $i
        exit 0
      fi
    fi
  fi
  #clean up re-encoded file
  rm -f $SINK
done

echo "None of the encondings worked. You're stuck."
exit 3
Joao Encarnacao
sumber