ฉันมีไฟล์ในการเข้ารหัส 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เป็นต้น) และคอมไพล์ด้วยตัวเองไบนารีจะไม่มีให้ในหน้านี้