Làm cách nào để xác định mã hóa tệp trong OS X?


170

Tôi đang cố gắng nhập một số ký tự UTF-8 vào tệp LaTeX trong TextMate (cho biết mã hóa mặc định của nó là UTF-8), nhưng LaTeX dường như không hiểu chúng.

Chạy cat my_file.texhiển thị các ký tự đúng trong Terminal. Chạy ls -alcho thấy một cái gì đó tôi chưa từng thấy trước đây: "@" trong danh sách tệp:

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

(Và, vâng, tôi đang sử dụng \usepackage[utf8]{inputenc}trong LaTeX.)

Tôi đã tìm thấy iconv, nhưng dường như không thể cho tôi biết mã hóa là gì - nó sẽ chỉ chuyển đổi khi tôi tìm ra nó.


Theo kinh nghiệm của tôi, lệnh tệp (1) luôn rất tốt trong việc đoán mã hóa của tệp. Tôi không biết liệu nó có đủ thông minh để sử dụng thuộc tính mở rộng của tệp com.apple.TextEncoding hay không.
Edward Falk

Câu trả lời:


33

@nghĩa là tệp có các thuộc tính tệp mở rộng được liên kết với nó. Bạn có thể truy vấn chúng bằng cách sử dụng getxattr()chức năng.

Không có cách xác định để phát hiện mã hóa của một tập tin. Đọc câu trả lời này , nó giải thích tại sao.

Có một công cụ dòng lệnh, enca , cố gắng đoán mã hóa. Bạn có thể muốn kiểm tra nó.


1
Tôi đã giả định rằng OSX lưu trữ mã hóa dưới dạng siêu dữ liệu. Tôi hiểu nội dung tập tin chỉ là một cụm bit và không có mã hóa vốn có.
James A. Rosen

1
@ JamesA.Rosen Các ứng dụng OS X như TextEdit lưu trữ mã hóa tệp dưới dạng một thuộc tính (có tên là "com.apple.TextEncoding"). Rất có khả năng các thuộc tính được chỉ định bởi @bao gồm thuộc tính mã hóa tệp. Bạn có thể sử dụng lệnh xattr -p com.apple.TextEncoding <filename>để xem thuộc tính mã hóa nếu nó tồn tại.
bames53

1
Bạn có thể giải thích làm thế nào để sử dụng getxattr? Tôi không thể sử dụng nó.
MeV

1
Đó là một chức năng gọi bạn sẽ sử dụng nếu bạn muốn viết một chương trình. Từ dòng lệnh, chỉ cần gõ ls -l@ <filename>để xem những thuộc tính nào được đặt cho tệp. Để xem thuộc tính thực tế, nhậpxattr -p com.apple.TextEncoding <filename>
Edward Falk

Để encalàm được brew install encavà bạn phải chỉ định ngôn ngữ nhưng không có ngôn ngữ nào hoạt động, vì vậy:enca FILENAME -L __
Shane

432

Sử dụng -Itùy chọn (đó là viết hoa i) trên lệnh tệp dường như hiển thị mã hóa tệp.

file -I {filename}

58
Tôi cần sử dụng -I
Casebash

7
Hàm này dường như không thể phân biệt được sự khác biệt giữa ASCII và UTF-8 (Có vẻ như chúng giống nhau đối với hầu hết các ký tự ở Hoa Kỳ, nhưng không phải tất cả, có lẽ là thứ sẽ phát hiện ra bit unicode)
BadPirate

14
ASCII và UTF8 giống nhau trừ khi có một ký tự ngoài OxFF trong tệp hoặc BOM.
davidtbernal

3
file -I *dường như hoạt động hoàn hảo đối với tôi (trên OSX). Một hệ thống phàn nàn về việc mã hóa một trong nhiều tệp mà không chỉ định tệp nào. Tất cả các tệp đều là ascii, ngoại trừ một tệp, đó là utf-8. Nhiều khả năng là thủ phạm.
mcv

1
@notJim Điều đó không chính xác. ASCII chỉ được xác định thông qua 0x7F, vì vậy mọi thứ nằm ngoài điểm đó rõ ràng không phải là ASCII. Unicode và Latin-1 có cùng điểm mã trong 0x80-0xFF nhưng không có mã hóa chung nào giống với Unicode-1 (vì điều đó vốn đã bị giới hạn ở 8 bit, quá ít so với Unicode).
tripleee

56

Trong Mac OS X, lệnh file -I(capital i) sẽ cung cấp cho bạn bộ ký tự phù hợp miễn là tệp bạn đang kiểm tra chứa các ký tự nằm ngoài phạm vi ASCII cơ bản.

Chẳng hạn, nếu bạn vào Terminal và sử dụng vi để tạo một tệp, vd. vi test.txt sau đó chèn một số ký tự và bao gồm một ký tự có dấu (thử ALT-e theo sau là e) sau đó lưu tệp.

Họ gõ file -I text.txtvà bạn sẽ nhận được một kết quả như thế này:

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


3
Tôi có thể xác nhận trường hợp OS X, charset = us-ascii hoặc charset = utf-8 tùy thuộc vào nội dung của tệp
Ben

nhưng dường như chỉ nhìn vào vài KB đầu tiên của tệp. trong trường hợp của tôi, lệnh vim tại stackoverflow.com/a/33644535/161022 xác định chính xác tệp là utf-8 trong khi filelệnh yêu cầuus-ascii
lmsurprenant

Thật vậy, có vẻ như tập tin gian lận vì lý do hiệu suất. Tôi vừa tạo một tệp ASCII 3 MB trên Ubuntu và thêm một vài ký tự UTF-8 vào cuối và nó vẫn báo cáo ASCII không phải UTF-8. Tôi đã thử tùy chọn -k (tiếp tục) nhưng sau đó nó báo cáo "dữ liệu" chứ không phải "UTF-8" nên vẫn không tốt.
Cloudranger

24
vim -c 'execute "silent !echo " . &fileencoding | q' {filename}

bí danh ở đâu đó trong cấu hình bash của tôi như

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

vì vậy tôi chỉ cần gõ

vic {filename}

Trên vanilla OSX Yosemite của tôi, nó mang lại kết quả chính xác hơn so với "tệp -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

1
Đây là câu trả lời duy nhất mang lại cho tôi những gì tôi cần - "latin1", trái ngược với "us-ascii". Mặc dù, tôi đã phải loại bỏ dấu gạch chéo ngược.
katy lavallee

Cảm ơn rất nhiều, tôi đã loại bỏ dấu gạch chéo ngược.
jmettraux

21

Bạn cũng có thể chuyển đổi từ loại tệp này sang loại tệp khác bằng lệnh sau:

iconv -f original_charset -t new_charset originalfile > newfile

ví dụ

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

13

Chỉ dùng:

file -I <filename>

Đó là nó.


2
Tôi không thể bận tâm bỏ phiếu, nhưng câu trả lời đó là hoàn toàn sai. Small -i nói không phân loại nội dung nếu đó là một tệp thông thường. -Tôi tương đương với --mime tạo ra chuỗi loại mime. Các công cụ osx hoạt động khác với các công cụ linux tiêu chuẩn.
sillyMunky

Vâng, đối với một tệp file -Iđược mã hóa Windows 1252 giúp tôi text/plain; charset=unknown-8bit. Mặc dù nó hoạt động tốt hơn cho một tập tin utf8 : text/plain; charset=utf-8.
MiB

8

Sử dụng filelệnh với --mime-encodingtùy chọn (ví dụ file --mime-encoding some_file.txt) thay vì tùy chọn -I hoạt động trên OS X và có thêm lợi ích là bỏ qua loại mime, "text / plain", mà bạn có thể không quan tâm.


ls -l @ a sẽ hiển thị các thuộc tính mở rộng . Nhìn vào trang man cho ls trên Yosemite, tôi không thấy tùy chọn - mã hóa thời gian.
rstackhouse

Bạn đang nói về filelệnh. Không biết rằng một người tồn tại. Gà mờ. Dù sao. Xin lỗi về downvote. VẬY sẽ không để tôi hoàn tác nó trừ khi có ai đó sửa câu trả lời này.
rstackhouse

4

LaTeX 8 bit cổ điển bị hạn chế rất nhiều trong đó các ký tự UTF8 có thể sử dụng; nó phụ thuộc rất nhiều vào mã hóa phông chữ bạn đang sử dụng và glyphs mà phông chữ đó có sẵn.

Vì bạn không đưa ra một ví dụ cụ thể, thật khó để biết chính xác vấn đề ở đâu - liệu bạn có đang cố sử dụng glyph mà phông chữ của bạn không có hoặc liệu bạn có sử dụng mã hóa phông chữ chính xác trong lần đầu tiên không địa điểm.

Dưới đây là một ví dụ tối thiểu cho thấy cách một vài ký tự UTF8 có thể được sử dụng trong tài liệu LaTeX:

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

Bạn có thể gặp nhiều may mắn hơn với mã hóa [utf8x], nhưng được cảnh báo một chút rằng nó không còn được hỗ trợ và có một số đặc điểm riêng so với [utf8] (theo như tôi nhớ; đã lâu rồi tôi mới xem nó). Nhưng nếu đó là mánh khóe, đó là tất cả những gì quan trọng đối với bạn.


3

Dấu @ có nghĩa là tệp có thuộc tính mở rộng . xattr filecũng hiển thị những thuộc tính nào, cũng xattr -l filehiển thị các giá trị thuộc tính (đôi khi có thể lớn - thử ví dụ xattr /System/Library/Fonts/HelveLTMMđể xem phông chữ kiểu cũ tồn tại trong ngã ba tài nguyên).


2

Nhập file myfile.texvào một thiết bị đầu cuối đôi khi có thể cho bạn biết mã hóa và loại tệp bằng cách sử dụng một loạt các thuật toán và số ma thuật. Nó khá hữu ích nhưng đừng dựa vào việc nó cung cấp thông tin cụ thể hoặc đáng tin cậy.

Một Localizable.stringstệp (được tìm thấy trong các ứng dụng Mac OS X được bản địa hóa) thường được báo cáo là tệp nguồn UTF-16 C.


1

Đồng bộ hóa nó! cho phép so sánh văn bản hoặc byte trong tất cả các mã hóa mà thư viện ICU cung cấp. Sử dụng tính năng đó bạn thường thấy ngay trang mã nào có ý nghĩa đối với dữ liệu của bạn.


1

Bạn có thể thử tải tệp vào cửa sổ firefox, sau đó chuyển đến Xem - Mã hóa ký tự. Cần có một dấu kiểm bên cạnh loại mã hóa của tệp.


0

Bạn đang sử dụng LaTeX nào? Khi tôi đang sử dụng teTeX, tôi phải tải xuống gói unicode theo cách thủ công và thêm gói này vào các tệp .tex của mình:

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

Bây giờ, tôi đã chuyển sang XeTeX từ gói TeXlive 2008 ( tại đây ), nó thậm chí còn đơn giản hơn:

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

Đối với việc phát hiện mã hóa của một tệp, bạn có thể chơi với file(1)(nhưng nó khá hạn chế) nhưng như người khác nói, điều đó thật khó khăn.


0

Một cách mạnh mẽ để kiểm tra mã hóa có thể chỉ là kiểm tra tệp trong trình soạn thảo hex hoặc tương tự. (hoặc viết chương trình để kiểm tra) Nhìn vào dữ liệu nhị phân trong tệp. Định dạng UTF-8 khá dễ nhận biết. Tất cả các ký tự ASCII là các byte đơn có giá trị dưới 128 (0x80) Chuỗi đa nhân theo mẫu được hiển thị trong bài viết wiki

Nếu bạn có thể tìm thấy một cách đơn giản hơn để có được một chương trình để xác minh mã hóa cho bạn, đó rõ ràng là một phím tắt, nhưng nếu tất cả các cách khác đều thất bại, thì đây sẽ là một mẹo nhỏ.


0

Tôi đã thực hiện kịch bản bash dưới đây, nó hoạt động với tôi.

Nó cố gắng đầu tiên iconvtừ bảng mã trả về bởi file --mime-encodingđếnutf-8 .

Nếu thất bại, nó đi qua tất cả các mã hóa và hiển thị độ lệch giữa tệp gốc và tệp được mã hóa lại. Nó bỏ qua các bảng mã tạo ra đầu ra khác biệt lớn ("lớn" như được định nghĩa bởiMAX_DIFF_LINES biến hoặc đối số đầu vào thứ hai), vì đó rất có thể là mã hóa sai.

Nếu "điều xấu" xảy ra do sử dụng tập lệnh này, đừng đổ lỗi cho tôi. Có một rm -ftrong đó, vì vậy có những con quái vật. Tôi đã cố gắng ngăn chặn các tác động bất lợi bằng cách sử dụng nó trên các tệp có hậu tố ngẫu nhiên, nhưng tôi không đưa ra bất kỳ lời hứa nào.

Đã thử nghiệm trên 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.