एक नमूना आदेश जो लक्षण प्रदर्शित करता है: sed 's/./@/' <<<$'\xfc'
विफल रहता है, क्योंकि बाइट 0xfc
एक मान्य UTF-8 वर्ण नहीं है।
ध्यान दें कि, इसके विपरीत, जीएनयू sed
(लिनक्स, लेकिन मैकओएस पर इंस्टॉल करने योग्य) बस एक त्रुटि रिपोर्ट किए बिना, अमान्य बाइट से गुजरता है।
पूर्व में स्वीकार किए गए उत्तर का उपयोग करना एक विकल्प है, यदि आपको अपने वास्तविक स्थान के लिए समर्थन खोने का मन नहीं है (यदि आप यूएस सिस्टम पर हैं और आपको विदेशी वर्णों से निपटने की आवश्यकता नहीं है, तो यह ठीक हो सकता है।)
हालाँकि, एक ही प्रभाव केवल एक आदेश के लिए तदर्थ हो सकता है :
LC_ALL=C sed -i "" 's|"iphoneos-cross","llvm-gcc:-O3|"iphoneos-cross","clang:-Os|g' Configure
नोट: क्या मायने रखती है एक है प्रभावी LC_CTYPE
की स्थापना C
, इसलिए LC_CTYPE=C sed ...
होता है सामान्य रूप से भी काम करते हैं, लेकिन अगर LC_ALL
(अलावा कुछ करने के लिए सेट होता है C
), यह अलग-अलग स्थान पर आ जाएगी LC_*
जैसे -category चर LC_CTYPE
। इस प्रकार, सबसे मजबूत दृष्टिकोण सेट करना है LC_ALL
।
हालांकि, (प्रभावी रूप से) स्ट्रिंग्स LC_CTYPE
को C
व्यवहार करने के लिए सेट करता है जैसे कि प्रत्येक बाइट का अपना चरित्र था ( एन्कोडिंग नियमों पर आधारित कोई व्याख्या नहीं की गई है), मल्टीबाइट-ऑन-डिमांड के लिए कोई संबंध नहीं है - यूटीएफ -8 एन्कोडिंग जो ओएस एक्स डिफ़ॉल्ट रूप से काम करता है। , जहां विदेशी पात्रों में बहुसंख्यक एनकोडिंग हैं ।
संक्षेप में: स्थापित करने LC_CTYPE
के लिएC
कारण बनता है खोल और उपयोगिताओं केवल अक्षर के रूप में बुनियादी अंग्रेजी अक्षरों (7-बिट ASCII रेंज में हैं) को मान्यता देने, ताकि विदेशी वर्ण। उदाहरण के लिए, अपर-लोअरकेस रूपांतरणों को विफल करने के लिए अक्षरों के रूप में व्यवहार नहीं किया जाएगा ।
फिर, यह ठीक हो सकता है यदि आपको मल्टीबाइट-एन्कोडेड वर्णों जैसे कि मेल नहीं खाते हैंé
, और बस ऐसे पात्रों को पास करना चाहते हैं ।
यदि यह अपर्याप्त है और / या आप मूल त्रुटि के कारण को समझना चाहते हैं (यह निर्धारित करना कि इनपुट बाइट्स की समस्या क्या है) और मांग पर एन्कोडिंग रूपांतरण करें, नीचे पढ़ें ।
समस्या यह है कि इनपुट फ़ाइल की एन्कोडिंग शेल के मेल से मेल नहीं खाती है।
अधिक विशेष रूप से, इनपुट फ़ाइल में वर्ण शामिल हैं जो UTF-8 में मान्य नहीं है (जैसा कि @Klas Lindbäck ने एक टिप्पणी में कहा है) - यही sed
त्रुटि संदेश द्वारा कहने की कोशिश कर रहा है invalid byte sequence
।
सबसे अधिक संभावना है, आपकी इनपुट फ़ाइल एकल-बाइट 8-बिट एन्कोडिंग का उपयोग करती है जैसे कि ISO-8859-1
, अक्सर "पश्चिमी यूरोपीय" भाषाओं को एन्कोड करने के लिए उपयोग किया जाता है।
उदाहरण:
उच्चारण पत्र à
में यूनिकोड कोडपॉइंट 0xE0
(224) है - उसी में ISO-8859-1
। हालांकि, की प्रकृति के कारण UTF-8 एन्कोडिंग, इस एकल कोडपॉइंट के रूप में प्रस्तुत किया जाता है 2 बाइट्स - 0xC3 0xA0
, जबकि पारित करने के लिए कोशिश कर रहा एक बाइट 0xE0
है अवैध UTF-8 के तहत।
यहाँ एक बाइट (ANSI-C- उद्धृत बैश स्ट्रिंग ( ) जो बाइट बनाने के लिए उपयोग होती है ) के रूप में प्रतिनिधित्व के साथ, एन्कोडेड स्ट्रिंग का उपयोग करके समस्या का प्रदर्शन है।voilà
ISO-8859-1
à
$'...'
\x{e0}
ध्यान दें कि sed
कमांड प्रभावी रूप से एक नो-ऑप है जो केवल इनपुट से गुजरता है, लेकिन हमें त्रुटि को भड़काने के लिए इसकी आवश्यकता है:
# -> 'illegal byte sequence': byte 0xE0 is not a valid char.
sed 's/.*/&/' <<<$'voil\x{e0}'
बस समस्या को अनदेखा करने के लिए , उपरोक्त LCTYPE=C
दृष्टिकोण का उपयोग किया जा सकता है:
# No error, bytes are passed through ('á' will render as '?', though).
LC_CTYPE=C sed 's/.*/&/' <<<$'voil\x{e0}'
यदि आप यह निर्धारित करना चाहते हैं कि इनपुट के कौन से हिस्से समस्या का कारण बनते हैं , तो निम्न प्रयास करें:
# Convert bytes in the 8-bit range (high bit set) to hex. representation.
# -> 'voil\x{e0}'
iconv -f ASCII --byte-subst='\x{%02x}' <<<$'voil\x{e0}'
आउटपुट आपको सभी बाइट्स दिखाएगा जिसमें हेक्साडेसिमल रूप में उच्च बिट सेट (बाइट्स जो 7-बिट एएससीआईआई सीमा से अधिक होता है) है। (ध्यान दें, हालांकि, इसमें सही रूप से एन्कोडेड UTF-8 मल्टीबाइट अनुक्रम शामिल हैं - विशेष रूप से अमान्य-इन-यूटीएफ -8 बाइट्स की पहचान करने के लिए एक अधिक परिष्कृत दृष्टिकोण की आवश्यकता होगी।)
मांग पर एन्कोडिंग रूपांतरण करना :
मानक उपयोगिता iconv
का उपयोग ( -t
) और / या ( -f
) एन्कोडिंग में बदलने के लिए किया जा सकता है ; iconv -l
सभी समर्थित लोगों को सूचीबद्ध करता है।
उदाहरण:
उपरोक्त उदाहरण पर निर्माण, ISO-8859-1
शेल में प्रभाव से एन्कोडिंग में कनवर्ट करें ( LC_CTYPE
जो UTF-8
डिफ़ॉल्ट रूप से आधारित है),
# Converts to UTF-8; output renders correctly as 'voilà'
sed 's/.*/&/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')"
ध्यान दें कि यह रूपांतरण आपको विदेशी पात्रों से ठीक से मेल खाने देता है :
# Correctly matches 'à' and replaces it with 'ü': -> 'voilü'
sed 's/à/ü/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')"
ISO-8859-1
प्रोसेसिंग के बाद इनपुट BACK को कन्वर्ट करने के लिए , परिणाम को दूसरे iconv
कमांड पर पाइप करें :
sed 's/à/ü/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')" | iconv -t ISO-8859-1