TL; DR:
grep -axv '.*' out.txt
uzun cevap
Her iki mevcut cevap da son derece yanıltıcı ve temel olarak yanlıştır.
Test etmek için, bu iki dosyayı alın (çok saygın bir geliştiriciden: Markus Kuhn):
$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt
$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
gösteri
Birincisi UTF-8-demo.txt
, UTF-8'in birçok dil, matematik, braille ve diğer birçok yararlı karakter türünü ne kadar iyi sunabileceğini göstermek için tasarlanmış bir dosyadır. Bir metin düzenleyicisine bir göz atın (utf-8'i anlayan) ve birçok örnek göreceksiniz ve hayır �
.
Yanıtın önerdiği test: karakter aralığını sınırlamak \x00-\x7F
bu dosyadaki hemen hemen her şeyi reddedecektir.
Bu çok yanlış ve bu dosyada hiçbiri olmadığı için hiçbirini kaldırmayacak�
.
Bu cevapta önerilen testi kullanmak 72.5 %
dosyanın kaldırılmasını sağlayacaktır :
$ grep -oP "[^\x00-\x7F]" UTF-8-demo.txt | tr -d '\n' | wc -c
10192
$ cat UTF-8-demo.txt | wc -c
14058
Bu (en pratik amaçlar için) tüm dosyadır. Mükemmel geçerli karakterleri göstermek için çok iyi tasarlanmış bir dosya.
Ölçek
İkinci dosya utf-8 okuyucularının iyi bir iş çıkardığını doğrulamak için çeşitli sınır durumlarını denemek üzere tasarlanmıştır. İçinde bir ' ' gösterilmesine neden olacak birçok karakter içeriyor. Ancak, kullanılacak diğer yanıt önerisi (seçilen) file
bu dosyayla büyük ölçüde başarısız olur. Yalnızca sıfır bayt ( \0
) (teknik olarak geçerli ASCII olan) ve bir \x7f
bayt (DEL - delete) (açıkça ASCII karakteridir ) kaldırılması tüm dosyayı file
komut için geçerli hale getirir :
$ cat UTF-8-test.txt | tr -d '\0\177' > a.txt
$ file a.txt
a.txt: Non-ISO extended-ASCII text, with LF, NEL line terminators
Sadece gelmez file
algılamak için başarısız birçok yanlış karakterler, aynı zamanda bir UTF-8 kodlanmış dosya olduğunu tespit ve rapor için başarısız.
Ve evet, file
UTF-8 kodlu metni algılayabilir ve raporlayabilir:
$ echo "ééakjfhhjhfakjfhfhaéá" | file -
/dev/stdin: UTF-8 Unicode text
Ayrıca, file
1 ila 31 aralığındaki kontrol karakterlerinin çoğunun ASCII olarak rapor verememesi. ( file
) Bazı aralıkları şöyle bildirir data
:
$ printf '%b' "$(printf '\\U%x' {1..6})" | file -
/dev/stdin: data
Diğerleri ASCII text
:
$ printf '%b' "$(printf '\\U%x' 7 {9..12})" | file -
/dev/stdin: ASCII text
Yazdırılabilir karakter aralığı olarak (yeni satırlarla):
$ printf '%b' "$(printf '\\U%x' {32..126} 10)" | file -
/dev/stdin: ASCII text
Ancak bazı aralıklar tuhaf sonuçlara neden olabilir:
$ printf '%b' "$(printf '\\U%x' {14..26})" | file -
/dev/stdin: Atari MSA archive data, 4113 sectors per track, starting track: 5141, ending track: 5655
Program file
metni algılamak için bir araç değil , yürütülebilir programlarda veya dosyalarda sihirli sayıları algılamak için bir araçtır .
Aralıkları file
algılar ve bulduğum bildirilen karşılık gelen tip:
Bir bayt değerleri, çoğunlukla ascii:
{1..6} {14..26} {28..31} 127 :data
{128..132} {134..159} :Non-ISO extended-ASCII text
133 :ASCII text, with LF, NEL line terminators
27 :ASCII text, with escape sequences
13 :ASCII text, with CR, LF line terminators
8 :ASCII text, with overstriking
7 {9..12} {32..126} :ASCII text
{160..255} :ISO-8859 text
Utf-8 kodlu aralıklar:
{1..6} {14..26} {28..31} 127 :data
27 :ASCII text, with escape sequences
13 :ASCII text, with CR, LF line terminators
8 :ASCII text, with overstriking
7 {9..12} {32..126} :ASCII text
{128..132} {134..159} :UTF-8 Unicode text
133 :UTF-8 Unicode text, with LF, NEL line terminators
{160..255} :UTF-8 Unicode text
{256..5120} :UTF-8 Unicode text
Olası bir çözüm aşağıda yatıyor.
Önceki Yanıt.
Gönderdiğiniz karakterin Unicode değeri:
$ printf '%x\n' "'�"
fffd
Evet, bu bir Unicode Karakter 'DEĞİŞTİRME KARAKTERİ' (U + FFFD) . Bu, metinde bulunan geçersiz Unicode karakterlerin yerine geçmek için kullanılan bir karakterdir . Gerçek bir karakter değil, bir "görsel yardım" dır. Geçersiz UNICODE karakterleri içeren tüm satırları bulmak ve listelemek için şunu kullanın:
grep -axv '.*' out.txt
ancak yalnızca herhangi bir karakterin geçersiz olup olmadığını tespit etmek istiyorsanız, şunu kullanın:
grep -qaxv '.*' out.txt; echo $?
Sonuç 1
dosya temizse, aksi takdirde sıfır olur 0
.
Sorduğunuz şey şuysa: �
karakteri nasıl bulacağınız , o zaman şunu kullanın:
➤ a='Basically, if the file "out.txt" contains "�" anywhere in the file I'
➤ echo "$a" | grep -oP $(printf %b \\Ufffd)
�
Veya sisteminiz UTF-8 metnini doğru bir şekilde işliyorsa, basitçe:
➤ echo "$a" | grep -oP '�'
�
grep
uzun unicode anlar (bu çok daha yavaş yapar, bu yüzden ascii dizeleri aramak içinLANG=C grep
, a büyük bir performans iyileştirmedir).