मैं UTF-8 फ़ाइल से BOM कैसे निकाल सकता / सकती हूं?


63

मेरे पास UTF-8 में BOM के साथ एन्कोडिंग है और BOM को हटाना चाहते हैं। क्या BOM को फ़ाइल से निकालने के लिए कोई linux कमांड-लाइन टूल हैं?

$ file test.xml
test.xml:  XML 1.0 document, UTF-8 Unicode (with BOM) text, with very long lines


1
मैंने कुछ महीनों पहले ऐसा करने के लिए एक बहुत ही सरल उपकरण बनाया है: oskog97.com/read/?path=/small-scripts/killbom&referer=/… हो सकता है कि यह / us / स्थानीय / बिन में ऐसा कुछ स्थापित करने लायक हो आपके पास BOMs के साथ कई UTF-8 एन्कोडेड फाइलें हैं।
Oskar Skog

जवाबों:


76

यदि आप सुनिश्चित नहीं हैं कि यदि फ़ाइल में UTF-8 BOM है, तो यह (GNU कार्यान्वयन को मानते हुए sed) BOM को हटा देगा, यदि यह मौजूद है, या नहीं तो कोई परिवर्तन नहीं करेगा।

sed '1s/^\xEF\xBB\xBF//' < orig.txt > new.txt

आप मौजूदा फ़ाइल को -iविकल्प के साथ अधिलेखित कर सकते हैं :

sed -i '1s/^\xEF\xBB\xBF//' orig.txt

4
यह utf8 लोकेल में काम नहीं कर सकता है, लेकिन लोकेल ओवरराइड को c या पॉज़िक्स से जोड़ने से हमेशा काम चलेगा।
hildred

3
@ बच्चों को मैंने इसे en_US.UTF-8लोकेल के साथ परखा है और यह काम किया है। यह कब फेल होगा?
m13r

2
@ m13r, यह sed और संकलित विकल्पों के संस्करण पर निर्भर करता है। विफलता के मामले में यूनिकोड के चरित्र वर्गों के साथ एक बहुत ही नए संस्करण में तीन बाइट अनुक्रम को एक एकल चरित्र के रूप में लाया जाएगा जो तीन चरित्र अनुक्रम से मेल नहीं खाता है। हालाँकि ऐसे मामले में आप एक सोलह बिट चरित्र मैच कर सकते हैं। हालाँकि यह एक नई विशेषता है और सार्वभौमिक रूप से मौजूद नहीं है। यदि आप परीक्षण करना चाहते हैं तो मैं नवीनतम संस्करण को संकलित करने की सलाह देता हूं।
१२:२५ पर

4
यूनिकोड-सक्षम सेड के साथ काम करने के लिए इसे ठीक करने के लिए LC_ALL = C sed '1s / ^ \ xEF \ xBB \ xBF //'
जोशुआ

@CSM अच्छा है, लेकिन एक विशेष मामले के लिए यह काम नहीं करता है: Bevore: के -<U+FEFF>\chapter{xxx}बाद: +\chapter{xxx}^M स्पष्टीकरण: लेटेक्स-फ़ाइल में टाइपो के लिए एमएस-शब्द का उपयोग करना। लिनक्स के तहत लेटेक्स त्रुटियों का उल्लेख कर रहा है। आउटपुट एक गिट सिस्टम से है। मैं इस विशेष मामले को पकड़ने के लिए अभिव्यक्ति को कैसे बदल सकता हूं?
कटटन आई

64

UTM-8 में BOM का कोई मतलब नहीं है। वे आम तौर पर Microsoft OSes पर बोगस सॉफ़्टवेयर द्वारा गलती से जोड़े जाते हैं।

dos2unix इसे हटा देगा और Windows पाठ फ़ाइलों की अन्य idiosyncrasies का भी ध्यान रखेगा।

dos2unix test.xml

17
मैं मानता हूं कि UTF-8 एनकोडेड BOM का कोई मतलब नहीं है, लेकिन विश्वास करें या न करें, बहुत सारे लोग हैं जो सोचते हैं कि यह एक महान विचार है जो UTF-8 को अन्य 8-बिट एन्कोडिंग से अलग करने में मदद करता है। तो यह स्वाद की बात है। विंडोज नोटपैड उद्देश्य पर एक बीओएम जोड़ता है।
जोहान मायरेन

17
इससे कोई फर्क नहीं पड़ता कि यह समझ में आता है या नहीं, जब संदर्भ सिर्फ इस पर सवाल है कि इसे कैसे हटाया जाए? विकिपीडिया के अनुसार, नोटपैड को किसी फ़ाइल को UTF-8 के रूप में पहचानने के लिए BOM की आवश्यकता होती है, और Google डॉक्स इसे टेक्स्ट के रूप में निर्यात करते समय जोड़ता है। मुझे संदेह है कि वे सभी गलती से करते हैं
इल्काचू

टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
terdon

1
वहाँ लाइन अंत नहीं परिवर्तित करने का एक तरीका है और बस BOM के साथ हटा दें dos2unix?
m13r

2
@ m13r फिर इस उत्तर में sed स्क्रिप्ट का उपयोग करें । यह केवल बम को हटा देगा (यदि यह मौजूद है), और कुछ नहीं बदला जाएगा।
तीर

25

tailकमांड से फ़ाइल से BOM निकालना संभव है :

tail -c +4 withBOM.txt > withoutBOM.txt

2
क्यों 4? BOM में 3 बाइट हैं।
डेविएंटफैन

10
यदि आप इसे छोड़ना चाहते हैं तो @deviantfan आपको 4 वीं बाइट पर शुरू करने की आवश्यकता क्यों है।
स्टीफन चेज़लस जुएल

9
tail1 आधारित अनुक्रमण का उपयोग कर रहा है ?! WTF!
कोडइन्चोस 19

5
@CodesInChaos, tail -c -1या tail -c 1( tailआमतौर पर किसके लिए उपयोग किया जाता है) अंतिम बाइट से शुरू होने वाली सामग्री है, tail -c +1जो पहली बाइट से शुरू होती है। tail -c 0/ इसके tail -c +0लिए बहुत अधिक अनपेक्षित होगा।
स्टीफन चेजलस

2
@deviantfan: (dd bs=1 count=3 of=/dev/null; cat) <input >output। या जीएनयू के साथ (head -c3 >/dev/null; cat)- यहां तक ​​कि यूटीएफ 8 या अन्य गैर-सिंगलबाइट लोकेल में भी; GNU हेड 'चार' = बाइट करता है।
dave_thompson_085

20

VIM का उपयोग करना

  1. VIM में खुली फाइल:

    vi text.xml
    
  2. BOM एन्कोडिंग निकालें:

    :set nobomb
    
  3. सेव करके छोड़ो:

    :wq
    

अजीब तरह से एक मैक पर विम 8 के साथ, मेरे पास एक्सेल द्वारा बनाई गई एक सीएसवी utf-8 फ़ाइल है और यह इसके साथ शुरू होता है <feff>, फिर :set nobombभी इसे संशोधित या हटा नहीं सकता है।
dlamblin

5

आप उपयोग कर सकते हैं

LANG=C LC_ALL=C sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- filename

फ़ाइल की शुरुआत से बाइट ऑर्डर मार्क को हटाने के लिए, यदि इसके पास कोई है, साथ ही किसी भी सीआर एलएफ न्यूलाइन को केवल एलएफ में परिवर्तित करें। LANG=C LC_ALL=Cखोल आप कमांड डिफ़ॉल्ट सी लोकेल (यह भी डिफ़ॉल्ट POSIX स्थान के रूप में जाना जाता है), जहां बाइट आदेश मार्क के गठन तीन बाइट्स बाइट के रूप में इलाज कर रहे हैं में चलाना चाहते हैं बताता है। -iसेड करने का विकल्प इन-प्लेस का मतलब है। यदि आप उपयोग करते हैं -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

इतना है कि अगर मैं सभी सी स्रोत फ़ाइलों और हेडर (एमएस-डॉस से मेरा पुराना कोड, उदाहरण के लिए!) कहने के लिए इसे लागू करने की आवश्यकता है, तो मैं बस चलाता हूं।

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 -- "$@"?
स्टीफन चेजेलस 14

@ स्टीफनचेज़ेलस: क्योंकि मैं चाहता हूं कि स्क्रिप्ट तुरंत बाहर निकल जाए अगर कोई प्रतिस्थापन के साथ कोई समस्या है, जो sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@"नहीं करता है; यह एक निकास कोड लौटाता है, लेकिन यह बाहर निकलने से पहले तर्क सूची में सूचीबद्ध सभी फाइलों को संसाधित करता है।
नाममात्र पशु

@ स्टीफनचेज़लस: --फ़ाइल नाम (ओं) से पहले, निश्चित रूप से, महत्वपूर्ण है: इसके बिना, डैश के साथ शुरू होने वाले फ़ाइल नामों को sed द्वारा विकल्प माना जा सकता है। मैंने उन लोगों को अपने उत्तर में संपादित किया; याद दिलाने के लिए शुक्रिया!
नाममात्र पशु

0

हाल ही में मुझे यह छोटी कमांड-लाइन टूल मिली, जो मनमाने ढंग से UTF-8 एनकोडेड फाइलों पर BOM को जोड़ती या हटाती है: UTF BOM Utils ( github पर नया लिंक )

थोड़ा दोष, आप केवल सादे C ++ स्रोत कोड डाउनलोड कर सकते हैं। आपको मेकफाइल ( सीएमके के साथ , उदाहरण के लिए) बनाना होगा और इसे खुद से संकलित करना होगा, इस पृष्ठ पर बायनेरिज़ प्रदान नहीं किए गए हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.