ฉันมีไฟล์ในการเข้ารหัส UTF-8 ด้วย BOM และต้องการลบ BOM มีเครื่องมือบรรทัดคำสั่ง linux เพื่อลบ BOM จากไฟล์หรือไม่?
$ file test.xml
test.xml: XML 1.0 document, UTF-8 Unicode (with BOM) text, with very long lines
ฉันมีไฟล์ในการเข้ารหัส UTF-8 ด้วย BOM และต้องการลบ BOM มีเครื่องมือบรรทัดคำสั่ง linux เพื่อลบ BOM จากไฟล์หรือไม่?
$ file test.xml
test.xml: XML 1.0 document, UTF-8 Unicode (with BOM) text, with very long lines
คำตอบ:
หากคุณไม่แน่ใจว่าไฟล์นั้นมี UTF-8 BOM หรือไม่หากนี่คือการดำเนินการตาม GNU sed
) จะลบ BOM หากมีอยู่หรือไม่ทำการเปลี่ยนแปลงหากไม่มี
sed '1s/^\xEF\xBB\xBF//' < orig.txt > new.txt
คุณสามารถเขียนทับไฟล์ที่มีอยู่ด้วย-i
ตัวเลือก:
sed -i '1s/^\xEF\xBB\xBF//' orig.txt
en_US.UTF-8
สถานที่แล้วและใช้งานได้ มันจะล้มเหลวเมื่อใด
1s/
หมายถึงค้นหาเฉพาะบรรทัดแรกเท่านั้น บรรทัดอื่นไม่ได้รับผลกระทบ ^
วิธีการเดียวที่ตรงกับจุดเริ่มต้นของ (ตอนแรก) สาย \xEF\xBB\xBF
คือ UTF-8 BOM (สตริงเลขฐานสิบหกที่ใช้ Escape) //
หมายถึงการแทนที่ด้วยอะไร ฉันสามารถเพิ่ม1
ไปยังจุดสิ้นสุด (สำหรับ1s/^xEF\xBB\xBF//1
) ซึ่งจะหมายถึงเฉพาะการเกิดขึ้นครั้งแรกของรูปแบบในบรรทัด แต่เมื่อการค้นหาถูกยึดด้วย^
สิ่งนี้จะไม่สร้างความแตกต่างเลย หากไฟล์ไม่มี BOM ที่จุดเริ่มต้นของบรรทัดแรกรูปแบบจะไม่ตรงกันและทำให้ไม่มีการเปลี่ยนแปลง
BOM ไม่สมเหตุสมผลใน UTF-8 โดยทั่วไปจะมีการเพิ่มซอฟต์แวร์ผิดพลาดบน Microsoft OSes
dos2unix
จะลบมันและดูแลไอดีอื่น ๆ ของไฟล์ข้อความ Windows
dos2unix test.xml
dos2unix
หรือไม่
เป็นไปได้ที่จะลบ BOM ออกจากไฟล์ด้วยtail
คำสั่ง:
tail -c +4 withBOM.txt > withoutBOM.txt
tail
กำลังใช้การจัดทำดัชนีตาม 1! WTF!
tail -c -1
หรือtail -c 1
(สิ่งที่tail
ใช้โดยทั่วไป) เป็นเนื้อหาที่เริ่มต้นด้วยไบต์สุดท้ายtail -c +1
เริ่มต้นด้วยไบต์แรก tail -c 0
/ tail -c +0
สำหรับสิ่งนั้นจะไม่ได้ใช้งานง่ายขึ้น
(dd bs=1 count=3 of=/dev/null; cat) <input >output
@deviantfan: หรือกับ GNU (head -c3 >/dev/null; cat)
- แม้ใน UTF8 หรือโลแคลอื่นที่ไม่ใช่ซิงเกิลไบต์ หัวของ GNU ทำหน้าที่ 'char' = ไบต์
เปิดไฟล์ใน VIM:
vi text.xml
ลบการเข้ารหัส BOM:
:set nobomb
บันทึกและออก:
:wq
<feff>
แต่:set nobomb
ก็ไม่ได้แก้ไขหรือลบมัน
คุณสามารถใช้ได้
LANG=C LC_ALL=C sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- filename
เพื่อลบเครื่องหมายคำสั่งซื้อไบต์จากจุดเริ่มต้นของไฟล์ถ้ามีรวมถึงแปลงบรรทัดใหม่ CR LF เป็น LF เท่านั้น LANG=C LC_ALL=C
บอกเปลือกคุณต้องการคำสั่งในการทำงานในสถานที่เริ่มต้น C (ยังเป็นที่รู้จักสถาน POSIX เริ่มต้น) ที่สามไบต์รูปมาร์คเพื่อ byte จะถือว่าเป็นไบต์ -i
ตัวเลือกในการ sed หมายความว่าในสถานที่ ถ้าคุณใช้-i.old
แล้ว sed บันทึกไฟล์ต้นฉบับเป็นfilename.old
และไฟล์ใหม่ filename
(มีการปรับเปลี่ยนถ้ามี)
โดยส่วนตัวฉันชอบที่จะมีสิ่งนี้เป็น~/bin/fix-ms
; ตัวอย่างเช่น
#!/bin/dash
export LANG=C LC_ALL=C
if [ $# -gt 0 ]; then
for FILE in "$@" ; do
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$FILE" || exit 1
done
else
exec sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//'
fi
ดังนั้นถ้าฉันต้องใช้สิ่งนี้เพื่อบอกว่าไฟล์ต้นฉบับและส่วนหัวของ C ทั้งหมด (โค้ดเก่าของฉันจากยุค MS-DOS เช่น!) ฉันแค่เรียกใช้
find . -name '*.[CHch]' -print0 | xargs -r0 ~/bin/ms-fix
หรือถ้าฉันแค่ต้องการดูไฟล์ดังกล่าวโดยไม่แก้ไขมันฉันก็สามารถรันได้
~/bin/ms-fix < filename | less
และไม่เห็นสิ่งที่น่าเกลียด<U+FEFF>
ในเทอร์มินัล UTF-8 ของฉัน
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@"
?
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@"
ไม่ได้ทำ; มันจะส่งกลับรหัสทางออก แต่จะประมวลผลไฟล์ทั้งหมดที่ระบุไว้ในรายการอาร์กิวเมนต์ก่อนที่จะออก
--
แน่นอนว่าชื่อไฟล์ก่อนหน้านี้สำคัญ: โดยไม่มีชื่อไฟล์ที่ขึ้นต้นด้วยเส้นประอาจถูกพิจารณาว่าเป็นตัวเลือกโดย sed ฉันแก้ไขสิ่งเหล่านั้นในคำตอบของฉัน; ขอบคุณสำหรับการเตือน!
เมื่อเร็ว ๆ นี้ฉันพบเครื่องมือบรรทัดคำสั่งเล็ก ๆ นี้ซึ่งเพิ่มหรือลบ BOM ในไฟล์ที่เข้ารหัส UTF-8 arbitary: UTF BOM Utils ( ลิงก์ใหม่ที่ github)
ข้อเสียเปรียบเล็กน้อยคุณสามารถดาวน์โหลดได้เฉพาะซอร์สโค้ด C ++ เท่านั้น คุณต้องสร้าง makefile (ด้วยCMakeเป็นต้น) และคอมไพล์ด้วยตัวเองไบนารีจะไม่มีให้ในหน้านี้