ฉันจะกำหนดการเข้ารหัสไฟล์ใน OS X ได้อย่างไร


170

ฉันกำลังพยายามป้อนอักขระ UTF-8 บางตัวลงในไฟล์ LaTeX ในTextMate (ซึ่งระบุว่าการเข้ารหัสเริ่มต้นคือ UTF-8) แต่ดูเหมือนว่า LaTeX จะไม่เข้าใจพวกเขา

การวิ่งcat my_file.texแสดงตัวละครอย่างถูกต้องในเทอร์มินัล การวิ่งls -alแสดงบางสิ่งที่ฉันไม่เคยเห็นมาก่อน: รายการ "@" โดย:

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

(และใช่ฉันใช้\usepackage[utf8]{inputenc}ใน LaTeX)

ฉันได้พบiconvแล้ว แต่ดูเหมือนจะไม่สามารถบอกได้ว่าการเข้ารหัสคืออะไร - มันจะแปลงเมื่อฉันคิดออกเท่านั้น


จากประสบการณ์ของฉันคำสั่ง file (1) ค่อนข้างดีในการเดาการเข้ารหัสของไฟล์ ฉันไม่รู้ว่ามันฉลาดพอที่จะใช้แอตทริบิวต์เพิ่มเติมของไฟล์ com.apple.TextEncoding หรือไม่
Edward Falk

คำตอบ:


33

@หมายความว่าไฟล์มีไฟล์คุณลักษณะเพิ่มเติมที่เกี่ยวข้องกับมัน คุณสามารถค้นหาได้โดยใช้getxattr()ฟังก์ชั่น

ไม่มีวิธีที่ชัดเจนในการตรวจจับการเข้ารหัสไฟล์ อ่านคำตอบนี้มันอธิบายว่าทำไม

มีเครื่องมือบรรทัดคำสั่งencaที่พยายามเดาการเข้ารหัส คุณอาจต้องการตรวจสอบ


1
ฉันสมมติว่า OSX จัดเก็บการเข้ารหัสเป็นเมตาดาต้า ฉันเข้าใจว่าเนื้อหาไฟล์เป็นเพียงกลุ่มของบิตและไม่มีการเข้ารหัสโดยธรรมชาติ
เจมส์เอ Rosen

1
@ JamesA.Rosen แอป OS X เช่น TextEdit ทำการจัดเก็บการเข้ารหัสไฟล์เป็นแอตทริบิวต์ (ชื่อ "com.apple.TextEncoding") อาจเป็นไปได้ว่าแอตทริบิวต์ที่ระบุโดย@มีแอตทริบิวต์การเข้ารหัสไฟล์ คุณสามารถใช้คำสั่งxattr -p com.apple.TextEncoding <filename>เพื่อดูคุณสมบัติการเข้ารหัสหากมีอยู่
bames53

1
คุณช่วยอธิบายวิธีใช้ getxattr ได้ไหม ฉันไม่สามารถใช้งานได้
MeV

1
นั่นคือการเรียกใช้ฟังก์ชันที่คุณจะใช้หากคุณต้องการเขียนโปรแกรม จากบรรทัดคำสั่งเพียงพิมพ์ls -l@ <filename>เพื่อดูว่ามีการตั้งค่าคุณลักษณะใดสำหรับไฟล์ หากต้องการดูแอตทริบิวต์ที่แท้จริงให้พิมพ์xattr -p com.apple.TextEncoding <filename>
Edward Falk

ในการencaทำbrew install encaและคุณต้องระบุภาษา แต่ไม่มีงานดังนั้น:enca FILENAME -L __
เชน

433

การใช้ตัวเลือก-I(ที่เป็นตัวพิมพ์ใหญ่ i) ในคำสั่ง file ดูเหมือนว่าจะแสดงการเข้ารหัสไฟล์

file -I {filename}

58
ฉันต้องการใช้ -I
Casebash

7
ฟังก์ชั่นนี้ดูเหมือนจะไม่สามารถบอกความแตกต่างระหว่าง ASCII และ UTF-8 (ดูเหมือนว่าพวกมันจะเหมือนกันสำหรับตัวละครในอเมริกาส่วนใหญ่ แต่ไม่ใช่ทั้งหมดบางทีสิ่งที่จะตรวจจับบิต unicode)
BadPirate

14
ASCII และ UTF8 เหมือนกันยกเว้นว่ามีอักขระเกินกว่า OxFF ในไฟล์หรือ BOM
davidtbernal

3
file -I *ดูเหมือนว่าจะทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน (บน OSX) ระบบบ่นเกี่ยวกับการเข้ารหัสไฟล์หนึ่งในหลายไฟล์โดยไม่ได้ระบุว่าจะให้ไฟล์ใด ไฟล์ทั้งหมดเป็น ascii ยกเว้นไฟล์เดียวซึ่งเป็น utf-8 น่าจะเป็นผู้กระทำผิด
mcv

1
@notJim ไม่ถูกต้อง ASCII ถูกกำหนดผ่าน 0x7F เท่านั้นดังนั้นสิ่งที่อยู่นอกเหนือจากจุดนั้นจึงไม่ใช่ ASCII ที่ชัดเจน Unicode และ Latin-1 มีรหัสจุดเดียวกันใน 0x80-0xFF แต่ไม่มีการเข้ารหัส Unicode ทั่วไปซึ่งเหมือนกับ Latin-1 (เพราะโดยทั่วไปจะถูก จำกัด 8 บิตซึ่งน้อยเกินไปสำหรับ Unicode)
tripleee

56

ใน Mac OS X คำสั่งfile -I(ตัวพิมพ์ใหญ่ i) จะให้ชุดอักขระที่เหมาะสมแก่คุณตราบเท่าที่ไฟล์ที่คุณกำลังทดสอบมีอักขระอยู่นอกช่วง ASCII พื้นฐาน

เช่นถ้าคุณไปที่ Terminal และใช้ vi เพื่อสร้างไฟล์เช่น vi test.txt จากนั้นใส่อักขระบางตัวและใส่อักขระเน้นเสียง (ลอง ALT-e แล้วตามด้วย e) จากนั้นบันทึกไฟล์

พวกเขาพิมพ์file -I text.txtและคุณควรได้รับผลลัพธ์เช่นนี้:

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


3
ฉันสามารถยืนยันเคส OS X, charset = us-ascii หรือ charset = utf-8 ขึ้นอยู่กับเนื้อหาของไฟล์
Ben

แต่ดูเหมือนว่าจะดูเพียงไม่กี่ KB แรกของไฟล์ ในกรณีของฉันคำสั่ง vim ที่stackoverflow.com/a/33644535/161022ระบุไฟล์อย่างถูกต้องเป็น utf-8 ในขณะที่fileคำสั่งอ้างว่ามันus-ascii
lmsurprenant

อันที่จริงมันปรากฏไฟล์ที่โกงด้วยเหตุผลด้านประสิทธิภาพ ฉันเพิ่งสร้างไฟล์ ASCII ขนาด 3MB บน Ubuntu และเพิ่มตัวอักษร UTF-8 สองสามตัวและยังคงรายงานว่า ASCII ไม่ใช่ UTF-8 ฉันลองตัวเลือก -k (ไปต่อ) แต่ก็รายงานว่า "data" ไม่ใช่ "UTF-8" ดังนั้นจึงยังไม่ดี
Cloudranger

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

ใช้นามแฝงในการกำหนดค่า bash ของฉันเป็น

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

ดังนั้นฉันแค่พิมพ์

vic {filename}

สำหรับ Vanilla OSX Yosemite ของฉันมันให้ผลลัพธ์ที่แม่นยำกว่า "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

1
นี่เป็นคำตอบเดียวที่ให้สิ่งที่ฉันต้องการ - "latin1" ซึ่งตรงข้ามกับ "us-ascii" แม้ว่าฉันจะต้องลบแบ็กสแลช
katy lavallee

ขอบคุณมากฉันลบแบ็กสแลช
jmettraux

21

คุณยังสามารถแปลงจากประเภทไฟล์หนึ่งเป็นประเภทอื่นโดยใช้คำสั่งต่อไปนี้:

iconv -f original_charset -t new_charset originalfile > newfile

เช่น

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

13

เพียงใช้:

file -I <filename>

แค่นั้นแหละ.


2
ฉันไม่สามารถลงคะแนนเสียงได้ แต่คำตอบนั้นผิดทั้งหมด Small-i พูดว่าอย่าจัดหมวดหมู่เนื้อหาหากเป็นไฟล์ปกติ -I เทียบเท่ากับ --mime ซึ่งแสดงผลสตริงประเภท mime เครื่องมือ osx ทำงานแตกต่างจากเครื่องมือ linux มาตรฐาน
sillyMunky

ดีสำหรับการใช้ Windows 1252 ไฟล์ที่เข้ารหัสได้รับฉันfile -I text/plain; charset=unknown-8bitแม้ว่ามันจะทำงานได้ดีขึ้นสำหรับไฟล์ text/plain; charset=utf-8utf8:
MiB

8

การใช้fileคำสั่งพร้อม--mime-encodingตัวเลือก (เช่นfile --mime-encoding some_file.txt) แทนตัวเลือก -I ทำงานบน OS X และมีประโยชน์เพิ่มเติมในการละเว้นประเภท mime "text / plain" ซึ่งคุณอาจไม่สนใจ


ls -l @ a จะแสดงแอตทริบิวต์เพิ่มเติม เมื่อดูหน้า man สำหรับ ls บน Yosemite ฉันไม่เห็นตัวเลือกการเข้ารหัส - รหัส
rstackhouse

คุณกำลังพูดถึงfileคำสั่ง ไม่รู้ว่ามีอยู่จริง อ่อนหัด. อย่างไรก็ตาม. ขออภัยเกี่ยวกับ downvote ดังนั้นจะไม่ให้ฉันยกเลิกได้หากไม่มีใครแก้ไขคำตอบนี้
rstackhouse

4

LaTeX แบบคลาสสิก 8 บิตถูก จำกัด อย่างมากซึ่งสามารถใช้อักขระ UTF8 ได้ มันขึ้นอยู่กับการเข้ารหัสของแบบอักษรที่คุณใช้และรูปแบบอักษรที่มีให้ใช้

เนื่องจากคุณไม่ได้ให้ตัวอย่างที่เฉพาะเจาะจงมันยากที่จะทราบว่าปัญหาอยู่ตรงไหน - ไม่ว่าคุณจะพยายามใช้ glyph ที่ตัวอักษรของคุณไม่มีหรือว่าคุณไม่ได้ใช้การเข้ารหัสแบบอักษรที่ถูกต้องในครั้งแรก สถานที่.

นี่คือตัวอย่างเล็กน้อยที่แสดงให้เห็นว่าสามารถใช้อักขระ UTF8 ได้กี่ตัวในเอกสาร LaTeX:

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

คุณอาจมีโชคมากขึ้นด้วยการเข้ารหัส [utf8x] แต่โปรดเตือนเล็กน้อยว่ามันไม่ได้รับการสนับสนุนอีกต่อไปและมีนิสัยแปลก ๆ เมื่อเทียบกับ [utf8] (เท่าที่ฉันจำได้ แต่ถ้ามันใช้กลอุบายนั่นคือทั้งหมดที่สำคัญสำหรับคุณ


3

เครื่องหมาย @ เครื่องหมายหมายถึงไฟล์ที่มีคุณสมบัติการขยาย xattr fileแสดงให้เห็นว่ามันมีคุณสมบัติใดxattr -l fileแสดงค่าแอตทริบิวต์ด้วย (ซึ่งอาจมีขนาดใหญ่บางครั้ง - ลองเช่นxattr /System/Library/Fonts/HelveLTMMเพื่อดูแบบอักษรแบบเก่าที่มีอยู่ในส้อมทรัพยากร)


2

การพิมพ์file myfile.texเทอร์มินัลบางครั้งสามารถบอกการเข้ารหัสและประเภทของไฟล์โดยใช้อัลกอริธึมและหมายเลขมายากล มันมีประโยชน์พอสมควร แต่อย่าพึ่งพาข้อมูลที่เป็นรูปธรรม

Localizable.stringsไฟล์ (ที่พบในภาษาท้องถิ่นการใช้งาน Mac OS X) มักจะเป็นรายงานที่เป็นแฟ้มแหล่งที่มา UTF-16 C


1

Synalyze It! อนุญาตให้เปรียบเทียบข้อความหรือไบต์ในการเข้ารหัสข้อเสนอทั้งหมดของห้องสมุด ICU การใช้คุณสมบัตินั้นคุณจะเห็นได้ทันทีว่าโค้ดเพจใดที่เหมาะกับข้อมูลของคุณ


1

คุณสามารถลองโหลดไฟล์ลงในหน้าต่าง firefox จากนั้นไปที่ View - การเข้ารหัสอักขระ ควรมีเครื่องหมายถูกติดกับประเภทการเข้ารหัสของไฟล์


0

คุณใช้ LaTeX ตัวไหนอยู่ เมื่อฉันใช้ teTeX ฉันต้องดาวน์โหลดแพคเกจunicodeด้วยตนเองและเพิ่มลงในไฟล์. tex ของฉัน:

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

ตอนนี้ฉันได้เปลี่ยนไปใช้ XeTeX จากแพ็คเกจ TeXlive 2008 ( ที่นี่ ) มันง่ายกว่ามากขึ้น:

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

สำหรับการตรวจจับการเข้ารหัสของไฟล์คุณสามารถเล่นกับfile(1)(แต่มันค่อนข้าง จำกัด ) แต่เหมือนที่คนอื่นพูดว่ามันยาก


0

วิธีบังคับแบบไร้เดียงสาเพื่อตรวจสอบการเข้ารหัสอาจเป็นการตรวจสอบไฟล์ในโปรแกรมแก้ไข hex หรือคล้ายกัน (หรือเขียนโปรแกรมเพื่อตรวจสอบ) ดูข้อมูลไบนารี่ในไฟล์ รูปแบบ UTF-8 นั้นง่ายต่อการจดจำ อักขระ ASCII ทั้งหมดเป็นไบต์เดียวที่มีค่าต่ำกว่า 128 (0x80) ลำดับ Multibyte ตามรูปแบบที่แสดงในบทความ wiki

หากคุณสามารถหาวิธีที่ง่ายกว่าในการทำให้โปรแกรมตรวจสอบการเข้ารหัสสำหรับคุณนั่นคือทางลัด แต่ถ้าทุกอย่างล้มเหลวก็จะเป็นการหลอกลวง


0

ฉันใช้สคริปต์ทุบตีด้านล่างมันใช้งานได้สำหรับฉัน

มันพยายามครั้งแรกที่จะiconvได้จากการเข้ารหัสที่ส่งกลับโดยการfile --mime-encodingutf-8

หากไม่สำเร็จจะผ่านการเข้ารหัสทั้งหมดและแสดงความแตกต่างระหว่างไฟล์ต้นฉบับและไฟล์ที่เข้ารหัสใหม่ มันข้ามการเข้ารหัสที่สร้างเอาท์พุท diff ขนาดใหญ่ ("ใหญ่" ตามที่กำหนดโดยMAX_DIFF_LINESตัวแปรหรืออาร์กิวเมนต์อินพุตที่สอง) เนื่องจากสิ่งเหล่านั้นมีแนวโน้มที่จะเข้ารหัสผิด

หาก "สิ่งเลวร้าย" เกิดขึ้นจากการใช้สคริปต์นี้อย่าโทษฉัน มีrm -fอยู่ในนั้นดังนั้นจึงมีสัตว์ประหลาด ฉันพยายามป้องกันผลข้างเคียงจากการใช้ไฟล์ที่มีคำต่อท้ายแบบสุ่ม แต่ฉันไม่ได้สัญญาใด ๆ

ทดสอบกับดาร์วิน 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.