Belirti gösteren bir örnek komut: sed 's/./@/' <<<$'\xfc'
başarısız olur, çünkü bayt 0xfc
geçerli bir UTF-8 karakteri değildir.
Bunun tersine, GNU'nun sed
(Linux, ancak macOS'a da yüklenebilir) bir hata bildirmeden geçersiz baytı ilettiğini unutmayın.
Daha önce kabul edilen cevabı kullanmak, gerçek yerel ayarınız için destek kaybetmemeniz durumunda bir seçenektir (bir ABD sistemindeyseniz ve asla yabancı karakterlerle uğraşmanız gerekmiyorsa, bu iyi olabilir.)
Ancak, aynı etki yalnızca tek bir komut için geçici olabilir :
LC_ALL=C sed -i "" 's|"iphoneos-cross","llvm-gcc:-O3|"iphoneos-cross","clang:-Os|g' Configure
Not: Önemli olan bir olan etkili LC_CTYPE
ayarı C
, bu nedenle LC_CTYPE=C sed ...
olur normalde eğer ayrıca iş, ama LC_ALL
(dışında bir set olur C
), bireysel geçersiz kılar LC_*
gibi -Kategoriler değişkenleri LC_CTYPE
. Böylece, en sağlam yaklaşım ortaya koymaktır LC_ALL
.
Ancak, (etkili) ayarı LC_CTYPE
için C
davranır dizeleri her bayt olsaydı kendi karakter olarak ( hayır ile kodlama kurallara dayalı yorumlama yapılır), hiçbir konuda için - multibyte-on-demand - UTF-8 kodlama OS X varsayılan olarak istihdam ettiğini burada yabancı karakterlerin çok baytlı kodlamaları vardır .
Özetle: ayar LC_CTYPE
içinC
nedenler sadece temel İngilizce harfleri harfleri (7 bitlik ASCII aralığında olanlar) tanımak kabuk ve yardımcı programları, böylece yabancı karakter. harf olarak değerlendirilmez ve örneğin büyük / küçük harf dönüşümlerinin başarısız olmasına neden olur.
Yine, gibi çok baytlı kodlanmış karakterlerle eşleşmeniz gerekmiyorsa é
ve bu karakterleri iletmek istiyorsanız bu iyi olabilir .
Bu yetersizse ve / veya orijinal hatanın nedenini (soruna hangi girdi baytlarının neden olduğunu belirleme dahil) anlamak ve talep üzerine kodlama dönüşümleri gerçekleştirmek istiyorsanız , aşağıda okuyun .
Sorun, girdi dosyasının kodlamasının kabuğunkiyle eşleşmemesidir.
Daha spesifik olarak, girdi dosyası UTF-8'de geçerli olmayan bir şekilde kodlanmış karakterler içerir (bir açıklamada @Klas Lindbäck belirtildiği gibi) - sed
hata mesajının söylemeye çalıştığı şey budur invalid byte sequence
.
Büyük olasılıkla, giriş dosyası kullanır kodlayan tek bayt 8-bit gibi ISO-8859-1
sık kodlamak "Batı Avrupa" dil için kullanılabilir.
Misal:
Aksanlı harf à
Unicode kod noktasına 0xE0
(224) sahiptir - ile aynıdır ISO-8859-1
. Bununla birlikte, doğası gereği , UTF-8 kodlama bu tek kod noktası olarak temsil edilir 2 bayt - 0xC3 0xA0
, geçmeye çalışırken ise tek bir bayt 0xE0
olup , geçersiz UTF-8 markası altında.
Aşağıda , bir bayt olarak temsil edilen ( bayt oluşturmak için kullanılan bir ANSI-C-alıntılı bash dizesi ( ) aracılığıyla) olarak kodlanan dizeyi kullanan sorunun bir gösterimi verilmiştir :voilà
ISO-8859-1
à
$'...'
\x{e0}
O Not sed
komut sadece içinden girişini geçer no-op etkin bir, ama biz o hatayı kışkırtmak gerekir:
# -> 'illegal byte sequence': byte 0xE0 is not a valid char.
sed 's/.*/&/' <<<$'voil\x{e0}'
Sorunu basitçe göz ardı etmek için yukarıdaki LCTYPE=C
yaklaşım kullanılabilir:
# No error, bytes are passed through ('á' will render as '?', though).
LC_CTYPE=C sed 's/.*/&/' <<<$'voil\x{e0}'
Sorunun hangi bölümlerin soruna neden olduğunu belirlemek istiyorsanız aşağıdakileri deneyin:
# 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}'
Çıktı, onaltılı biçimde yüksek bit ayarlı (7 bit ASCII aralığını aşan bayt) tüm baytları gösterir. (Bununla birlikte, bunun doğru şekilde kodlanmış UTF-8 çok baytlı dizileri de içerdiğine dikkat edin - UTF-8 baytında geçersiz olanları özel olarak tanımlamak için daha karmaşık bir yaklaşıma ihtiyaç duyulacaktır.)
İstek üzerine kodlama dönüşümleri gerçekleştirme :
Standart yardımcı program iconv
( -t
) ve / veya ( -f
) kodlamalarına dönüştürmek için kullanılabilir ; iconv -l
desteklenenlerin tümünü listeler.
Örnekler:
Dönüştüğünde ISO-8859-1
(göre kabuğu etkisi kodlama LC_CTYPE
olup, UTF-8
yukarıdaki örnek üzerine inşa varsayılan tabanlı):
# Converts to UTF-8; output renders correctly as 'voilà'
sed 's/.*/&/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')"
Bu dönüşümün yabancı karakterleri doğru şekilde eşleştirmenize izin verdiğini unutmayın :
# Correctly matches 'à' and replaces it with 'ü': -> 'voilü'
sed 's/à/ü/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')"
ISO-8859-1
İşlemden sonra BACK girişini dönüştürmek için sonucu başka bir iconv
komuta yönlendirmeniz yeterlidir :
sed 's/à/ü/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')" | iconv -t ISO-8859-1