बाइट-ऑर्डर मार्क को हटाने के लिए awk का उपयोग करना


105

BOMawk को हटाने के लिए कोई स्क्रिप्ट (संभवतः एक-लाइनर) कैसे होगी ?

विशिष्टता:

  • पहले के बाद हर लाइन प्रिंट करें ( NR > 1)
  • पहली पंक्ति के लिए: यदि यह #FE #FFया के साथ शुरू होता है #FF #FE, तो उन्हें हटा दें और बाकी को प्रिंट करें

जवाबों:


114

इसे इस्तेमाल करे:

awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE

पहले रिकॉर्ड (लाइन) पर, BOM वर्ण हटाएं। हर रिकॉर्ड को प्रिंट करें।

या थोड़ा कम, इस ज्ञान का उपयोग करके कि awk में डिफ़ॉल्ट क्रिया रिकॉर्ड को प्रिंट करना है:

awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE

1 सबसे छोटी स्थिति है जो हमेशा सच का मूल्यांकन करती है, इसलिए प्रत्येक रिकॉर्ड मुद्रित होता है।

का आनंद लें!

- जोड़ें -

यूनिकोड बाइट ऑर्डर मार्क (बीओएम) सामान्य प्रश्न में प्रत्येक एन्कोडिंग के लिए सटीक बीओएम बाइट्स को सूचीबद्ध करने वाली निम्न तालिका शामिल है:

Bytes         |  Encoding Form
--------------------------------------
00 00 FE FF   |  UTF-32, big-endian
FF FE 00 00   |  UTF-32, little-endian
FE FF         |  UTF-16, big-endian
FF FE         |  UTF-16, little-endian
EF BB BF      |  UTF-8

इस प्रकार, आप देख सकते हैं कि उपरोक्त तालिका से बीओएम बाइट्स के \xef\xbb\xbfअनुरूप कैसे हैं EF BB BF UTF-8


1
ऐसा लगता है कि उप कथन के बीच में बिंदी बहुत अधिक है (कम से कम, मेरी जाग इसके बारे में शिकायत करती है)। इसके अलावा यह वही है जो मैंने खोजा, धन्यवाद!
बोल्ड्यूइन

5
हालाँकि, यह समाधान केवल UTF-8 एन्कोडेड फ़ाइलों के लिए काम करता है । दूसरों के लिए, जैसे यूटीएफ -16, इसी बीओएम प्रतिनिधित्व के लिए विकिपीडिया देखें: en.wikipedia.org/wiki/Byte_order_mark
Boldewyn

2
तो: awk '{if(NR==1)sub(/^\xef\xbb\xbf/,"");print}' INFILE > OUTFILEऔर सुनिश्चित करें कि शख्सियत और OUTFILE अलग हैं!
स्टीव क्ले

1
यदि आप उपयोग perl -i.orig -pe 's/^\x{FFFE}//' badfileकरते हैं तो आप एन्कोडिंग के लिए अपने PERL_UNICODE और / या PERLIO एन्वारिएबल्स पर भरोसा कर सकते हैं। PERL_UNICODE = SD UTF-8 के लिए काम करेगा; दूसरों के लिए, आपको PERLIO की आवश्यकता होगी।
टॉचर

1
शायद थोड़ा छोटा संस्करण है:awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1'
TrueY

122

GNU sed(लिनक्स या सिगविन पर) का उपयोग करना :

# Removing BOM from all text files in current directory:
sed -i '1 s/^\xef\xbb\xbf//' *.txt

FreeBSD पर:

sed -i .bak '1 s/^\xef\xbb\xbf//' *.txt

जीएनयू या फ्रीबीएसडी का उपयोग करने का लाभ sed: -iपैरामीटर का अर्थ है "जगह में", और पुनर्निर्देशन या अजीब चाल की आवश्यकता के बिना फ़ाइलों को अपडेट करेगा।

मैक पर:

awkएक अन्य उत्तर में यह समाधान काम करता है , लेकिन sedऊपर का आदेश काम नहीं करता है। कम से कम मैक (सिएरा) sedप्रलेखन में हेक्साडेसिमल से बचने वाले अला का समर्थन करने का उल्लेख नहीं है \xef

एक समान ट्रिक को किसी भी प्रोग्राम के साथ टूल्यूटsponge से पाइपिंग द्वारा प्राप्त किया जा सकता है :

awk '…' INFILE | sponge INFILE

5
मैंने मैक ओएस एक्स पर सटीक रूप से दूसरी कमांड की कोशिश की और परिणाम "सफलता" था, लेकिन प्रतिस्थापन वास्तव में नहीं हुआ।
तर्जुक

1
यह ध्यान देने योग्य है कि ये आदेश एक विशिष्ट बाइट अनुक्रम को प्रतिस्थापित करते हैं, जो संभव बाइट-ऑर्डर-मार्क्स में से एक है । हो सकता है कि आपकी फ़ाइल में एक अलग BOM अनुक्रम था। (मैं इसके अलावा अन्य मदद नहीं कर सकता, जैसा कि मेरे पास एक मैक नहीं है)
डेनिलसन सा माया

3
जब मैंने 0xef 0xbb 0xbf को BOM के रूप में उपयोग करने वाली फ़ाइल पर OS X पर दूसरी कमांड की कोशिश की, तो यह वास्तव में प्रतिस्थापन नहीं किया।
जॉन वाइसमैन

OSX में, मैं इसे केवल पर्ल के माध्यम से काम करने के लिए प्राप्त कर सकता हूं, जैसा कि यहां दिखाया गया है: stackoverflow.com/a/9101056/2063546
इयान

OS X El Capitan पर 10.11.6, यह काम नहीं करता है, लेकिन आधिकारिक उत्तर stackoverflow.com/a/1068700/9636 ठीक काम करता है।
हीथ बॉर्डर्स

42

जाग नहीं है, लेकिन सरल:

tail -c +4 UTF8 > UTF8.nobom

BOM की जांच करने के लिए:

hd -n 3 UTF8

यदि BOM मौजूद है तो आप देखेंगे: 00000000 ef bb bf ...


6
यूटीएफ -16 के लिए बीओएम 2 बाइट्स और यूटीएफ -32 के लिए 4 बाइट्स हैं, और निश्चित रूप से पहले स्थान पर यूटीएफ -8 में कोई व्यवसाय नहीं है।
टॉचर

2
@ करोलीहोरवथ हां, ठीक है। इसके उपयोग की अनुशंसा नहीं की जाती है। इससे सामान टूट जाता है। एन्कोडिंग को एक उच्च-स्तरीय प्रोटोकॉल द्वारा निर्दिष्ट किया जाना चाहिए।
tchrist

1
@ टिचर: आपका मतलब है कि यह टूटी हुई चीजें तोड़ता है? :) उचित ऐप्स उस BOM को संभालने में सक्षम होना चाहिए।
कारोली होर्वाथ

7
@KarolyHorvath मेरा मतलब है कि यह बहुत सारे कार्यक्रमों को तोड़ता है । क्या मैंने ऐसा नहीं कहा? जब आप UTF-16 या UTF-32 एन्कोडिंग में एक स्ट्रीम खोलते हैं, तो डिकोडर BOM की गिनती नहीं करना जानता है। जब आप UTF-8 का उपयोग करते हैं, तो डिकोडर BOM को डेटा के रूप में प्रस्तुत करते हैं। यह असंख्य कार्यक्रमों में एक वाक्यविन्यास त्रुटि है। यहां तक ​​कि जावा के डिकोडर इस तरह से व्यवहार करते हैं, BY डिजाइन! UTF-8 फ़ाइलों पर BOMs गलत हैं और बट में दर्द होता है: वे एक त्रुटि हैं! वे कई चीजों को तोड़ते हैं। यहां तक ​​कि सिर्फ cat file1.utf8 file2.utf8 file3.utf3 > allfiles.utf8टूट जाएगा। कभी भी UTF-8 पर BOM का उपयोग न करें। अवधि।

6
hdओएस एक्स (10.8.2 के रूप में) पर उपलब्ध नहीं है, इसलिए एक के लिए जाँच करने के लिए UTF-8 बीओएम वहाँ आप निम्नलिखित का उपयोग कर सकते हैं: head -c 3 file | od -t x1
mklement0

21

CRLF लाइन अंत को LF में परिवर्तित करने के अलावा, dos2unixBOM को भी हटाता है:

dos2unix *.txt

dos2unix बिना BOM के भी UTM-16 फ़ाइलों को BOM (लेकिन बिना BOM के UTF-16 फ़ाइलों) में परिवर्तित करता है:

$ printf '\ufeffä\n'|iconv -f utf-8 -t utf-16be>bom-utf16be
$ printf '\ufeffä\n'|iconv -f utf-8 -t utf-16le>bom-utf16le
$ printf '\ufeffä\n'>bom-utf8
$ printf 'ä\n'|iconv -f utf-8 -t utf-16be>utf16be
$ printf 'ä\n'|iconv -f utf-8 -t utf-16le>utf16le
$ printf 'ä\n'>utf8
$ for f in *;do printf '%11s %s\n' $f $(xxd -p $f);done
bom-utf16be feff00e4000a
bom-utf16le fffee4000a00
   bom-utf8 efbbbfc3a40a
    utf16be 00e4000a
    utf16le e4000a00
       utf8 c3a40a
$ dos2unix -q *
$ for f in *;do printf '%11s %s\n' $f $(xxd -p $f);done
bom-utf16be c3a40a
bom-utf16le c3a40a
   bom-utf8 c3a40a
    utf16be 00e4000a
    utf16le e4000a00
       utf8 c3a40a

3

मुझे पता है कि सवाल यूनिक्स / लाइनक्स में निर्देशित किया गया था, सोचा कि यूनिक्स-चैलेंज्ड (विंडोज़ पर, यूआई के साथ) के लिए एक अच्छा विकल्प का उल्लेख करना उचित होगा।
मैं एक वर्डप्रेस परियोजना पर एक ही मुद्दे में भाग गया (बीओएम को आरएसएस फ़ीड और पृष्ठ सत्यापन के साथ समस्याएं पैदा हो रही थीं) और मुझे बीओएम के साथ खोजने के लिए काफी बड़ी निर्देशिका ट्री में सभी फाइलों को देखना पड़ा। बदले पायनियर नामक एक एप्लिकेशन मिला और इसमें:

बैच रनर -> खोज (सबफ़ोल्डर में सभी फ़ाइलों को खोजने के लिए) -> टेम्पलेट बदलें -> बाइनरी निकालें बीओएम (इसके लिए एक तैयार की गई खोज और प्रतिस्थापित टेम्पलेट है)।

यह सबसे सुरुचिपूर्ण समाधान नहीं था और इसे एक कार्यक्रम स्थापित करने की आवश्यकता थी, जो एक नकारात्मक पहलू है। लेकिन एक बार जब मुझे पता चला कि मेरे आसपास क्या चल रहा है, तो यह एक आकर्षण की तरह काम करता था (और 2300 में से 3 फाइलें मिलीं जो बीओएम के साथ थीं)।


1
मुझे बहुत खुशी हुई जब मैंने आपका समाधान पाया, हालाँकि मुझे कंपनी कंप्यूटर पर सॉफ़्टवेयर स्थापित करने का विशेषाधिकार नहीं है। आज तक बहुत समय लगा, जब तक कि मैं विकल्प का पता नहीं लगाता: पायथनस्क्रिप्ट प्लगइन के साथ नोटपैड ++ का उपयोग करना। superuser.com/questions/418515/… फिर भी धन्यवाद!
Hoàng Long
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.