TL; DR:
grep -axv '.*' out.txt
câu trả lời dài
Cả hai câu trả lời hiện tại là vô cùng sai lệch và về cơ bản là sai.
Để kiểm tra, Nhận hai tệp này (từ một nhà phát triển được đánh giá rất cao: 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
Bản giới thiệu
Đầu tiên UTF-8-demo.txt
là một tệp được thiết kế để cho thấy UTF-8 có khả năng trình bày nhiều ngôn ngữ, toán học, chữ nổi và nhiều loại ký tự hữu ích khác như thế nào. Hãy xem với một trình soạn thảo văn bản (hiểu utf-8) và bạn sẽ thấy rất nhiều ví dụ và không �
.
Bài kiểm tra mà một câu trả lời đề xuất: giới hạn phạm vi ký tự \x00-\x7F
sẽ từ chối hầu hết mọi thứ trong tệp này.
Điều đó là rất sai và sẽ không xóa bất kỳ �
vì không có gì trong tập tin đó .
Sử dụng bài kiểm tra được đề xuất trong câu trả lời đó sẽ xóa 72.5 %
tệp:
$ grep -oP "[^\x00-\x7F]" UTF-8-demo.txt | tr -d '\n' | wc -c
10192
$ cat UTF-8-demo.txt | wc -c
14058
Đó là (cho hầu hết các mục đích thực tế) toàn bộ tập tin. Một tập tin được thiết kế rất tốt để hiển thị các ký tự hoàn toàn hợp lệ.
Kiểm tra
Tệp thứ hai được thiết kế để thử một số trường hợp viền để xác nhận rằng các trình đọc utf-8 đang hoạt động tốt. Nó chứa bên trong nhiều ký tự sẽ khiến '' được hiển thị. Nhưng đề nghị trả lời khác (cái được chọn) để sử dụng file
không thành công với tệp này. Chỉ loại bỏ một byte 0 ( \0
) (về mặt kỹ thuật là ASCII hợp lệ) và một \x7f
byte (DEL - xóa) (rõ ràng cũng là một ký tự ASCII) sẽ làm cho tất cả các tệp hợp lệ cho file
lệnh:
$ 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
Không chỉ không file
phát hiện nhiều ký tự không chính xác mà còn không phát hiện và báo cáo rằng đó là tệp được mã hóa UTF-8.
Và có, file
có thể phát hiện và báo cáo văn bản được mã hóa UTF-8:
$ echo "ééakjfhhjhfakjfhfhaéá" | file -
/dev/stdin: UTF-8 Unicode text
Ngoài ra, file
không báo cáo là ASCII, hầu hết các ký tự điều khiển trong phạm vi từ 1 đến 31. Nó ( file
) báo cáo một số phạm vi là data
:
$ printf '%b' "$(printf '\\U%x' {1..6})" | file -
/dev/stdin: data
Những người khác như ASCII text
:
$ printf '%b' "$(printf '\\U%x' 7 {9..12})" | file -
/dev/stdin: ASCII text
Là phạm vi ký tự có thể in (với dòng mới):
$ printf '%b' "$(printf '\\U%x' {32..126} 10)" | file -
/dev/stdin: ASCII text
Nhưng một số phạm vi có thể gây ra kết quả kỳ lạ:
$ printf '%b' "$(printf '\\U%x' {14..26})" | file -
/dev/stdin: Atari MSA archive data, 4113 sectors per track, starting track: 5141, ending track: 5655
Chương trình file
không phải là một công cụ để phát hiện văn bản, mà là để phát hiện các số ma thuật trong các chương trình hoặc tệp thực thi.
Phạm vi file
phát hiện và loại tương ứng được báo cáo tôi tìm thấy là:
Giá trị một byte, chủ yếu là 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
Phạm vi được mã hóa Utf-8:
{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
Một giải pháp có thể nằm dưới đây.
Trả lời trước.
Giá trị Unicode cho ký tự bạn đang đăng là:
$ printf '%x\n' "'�"
fffd
Đúng, đó là một ký tự Unicode 'ĐẶC ĐIỂM THAY THẾ' (U + FFFD) . Đó là một ký tự được sử dụng để thay thế bất kỳ ký tự Unicode không hợp lệ nào được tìm thấy trong văn bản. Nó là một "trợ giúp trực quan", không phải là một nhân vật thực sự. Để tìm và liệt kê mọi dòng đầy đủ chứa các ký tự UNICODE không hợp lệ, hãy sử dụng:
grep -axv '.*' out.txt
nhưng nếu bạn chỉ muốn phát hiện nếu có bất kỳ ký tự nào không hợp lệ, hãy sử dụng:
grep -qaxv '.*' out.txt; echo $?
Nếu kết quả là 1
tập tin sạch, nếu không sẽ bằng không 0
.
Nếu những gì bạn đang hỏi là: làm thế nào để tìm thấy �
nhân vật, thì, hãy sử dụng điều này:
➤ a='Basically, if the file "out.txt" contains "�" anywhere in the file I'
➤ echo "$a" | grep -oP $(printf %b \\Ufffd)
�
Hoặc nếu hệ thống của bạn xử lý chính xác văn bản UTF-8, chỉ cần:
➤ echo "$a" | grep -oP '�'
�
grep
từ lâu hiểu được unicode (làm cho nó chậm hơn nhiều, vì vậy để tìm kiếm chuỗi ascii, aLANG=C grep
là một cải tiến hiệu suất rất lớn).