ตรวจสอบไฟล์ ASCII ด้วยคำสั่ง file โดย shell scrript


5

ด้วยคำสั่ง file ฉันจำเป็นต้องตรวจสอบไฟล์หลายไฟล์ถ้าพวกเขา ASCII หรือรูปแบบอื่น ๆ

บางครั้งฉันได้รับจากคำสั่ง file:

  file1: ASCII English text

และบางครั้งฉันก็ได้รับคำตอบที่แตกต่างจากคำสั่ง file

  file2: Non-ISO extended-ASCII English text, with very long lines

ฉันไม่แน่ใจจริงๆถ้ามีคำตอบอื่นที่มีไวยากรณ์ต่างกัน

คำถามของฉันคือ:

ฉันเขียนไวยากรณ์ follwing ksh เพื่อตรวจสอบว่าไฟล์เป็น ASCII แต่ฉันไม่แน่ใจว่า

ไวยากรณ์ต่อไปนี้เป็นไวยากรณ์ที่ดีที่สุดเพื่อตรวจสอบรูปแบบ ASCII?

   [[ ` file  $some_file | grep –c ASCII ` = 1 ]] && print "you have ascii file for sure"

หากมีคนแนะนำอื่น ๆ ให้ยืนยันรูปแบบ ASCII แน่นอน! ฉันยินดีเป็นอย่างยิ่งที่ได้เห็น


ASCII? ในสมัยของอินเทอร์เน็ตและ Unicode? คุณต้องล้อเล่น.
grawity

คุณตระหนักดีว่าfileเป็นการเดาแบบแก้ปัญหาและไม่ใช่การรับประกันใช่ไหม yes | head -c $((2**20)) > blah; dd if=/dev/urandom bs=1 count=1024 >> blah; file blahพูดว่าblah: ASCII textแม้ว่ามันจะไม่
ephemient

ใช่ฉันเข้าใจ แต่สิ่งที่ฉันต้องทำถ้าฉันต้องการเลือกไฟล์ประเภทสิ่งที่ดีที่สุดที่จะทำ? ความคิดใด ๆ
เจนนิเฟอร์

คำตอบ:


8
if LC_ALL=C grep -q '[^[:print:][:space:]]' file; then
    echo "file contains non-ascii characters"
else
    echo "file contains ascii characters only"
fi

สวัสดี ephemient - โปรดอธิบาย LC_ALL = C ก่อนคำสั่ง grep ทำไม?
เจนนิเฟอร์

2
LC_ALL=Cบังคับgrepให้ถือว่า[[:print:]]เป็นคลาสอักขระ "ที่พิมพ์ได้ ASCII" มิฉะนั้นจะหมายถึง "พิมพ์ <สิ่งที่โลแคลปัจจุบันของคุณคือ>" ซึ่งอาจไม่ใช่ ASCII ตัวอย่างเช่นกล่อง Linux ส่วนใหญ่จะตั้งค่าด้วยโลแคล UTF-8 ซึ่งในกรณีนี้[[:print:]]จะจับคู่ลำดับอักขระที่ไม่ใช่ ASCII ที่เป็นอักขระ UTF-8 ที่ใช้ได้
ephemient

1
@jennifer: name=value commandเป็นไวยากรณ์สำหรับการตั้งค่าตัวแปรสภาพแวดล้อมชั่วคราวในกรณีนี้LC_ALLสำหรับคำสั่งเดียว การตั้งค่าภาษาเพื่อให้Cแน่ใจว่า[[:print:]]ตรงกับอักขระ ASCII เท่านั้น (และไม่เน้นอักขระจากภาษาของคุณ)
grawity

เหตุใดฉันจึงได้รับ "ไฟล์มีอักขระที่ไม่ใช่ ASCII" สำหรับ / etc / hosts อย่างที่คุณทราบว่าไฟล์โฮสต์คือไฟล์ ASCII
เจนนิเฟอร์

@ jennifer: แก้ไขแล้ว อาจรวมแท็บหรืออะไรแบบนั้น ฉันลืม[[:print:]]คือไม่ได้[[:graph:] ] [[:graph:][:space:]]
ephemient

1

เกี่ยวกับ...

if file -ib "$file" | grep -Eqs '^text/plain(;|$)'; then
    echo "It's text/plain."
fi

ฉันไม่รู้ว่าสามัญเป็น--mime-typeอย่างไร; หากเป็นมาตรฐานให้ใช้

if file -b --mime-type "$file" | grep -qs '^text/plain$'; then

หรือgrep -qs '^text/'สำหรับข้อความประเภทใดก็ได้


0

เนื่องจากคุณกำลังแยกวิเคราะห์ผลลัพธ์ด้วยรหัสฉันขอแนะนำให้ใช้-iตัวเลือกfileเพื่อให้มันส่งออกประเภทMIMEแทนสตริงที่เป็นมิตรกับมนุษย์ เอาต์พุตประเภท MIME นั้นปกติมากขึ้นและทำให้ง่ายต่อการจัดการกับโค้ด

สำหรับประเภทเอาต์พุตให้ดูที่ไฟล์ manกล่าวว่า:

/usr/share/file/magic
    Default list of magic numbers

/usr/share/file/magic.mime
    Default list of magic numbers, used to output  mime types
    when the -i option is specified.

ลองดูที่ไฟล์เหล่านั้นสำหรับทุกชนิด MIME fileที่จะสามารถรายงานการตรวจสอบที่ประเภทที่คุณจะดูแลเกี่ยวกับการส่งออกเมื่อแยกจาก text/ฉันสงสัยว่าสิ่งที่คุณจะดูแลคือชนิดไมม์เริ่มต้นด้วย

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