UTF-8로 인코딩된 텍스트 파일로 의심되는 문제가 있는 시퀀스를 발견했습니다. 이상한 점은 grep이 ASCII가 아닌 라인과 일치하지 않는 것 같다는 것입니다.
$ iconv -f utf8 -t iso88591 corrupt_part.txt --output corrupt_part.txt.conv
iconv: illegal input sequence at position 8
$ cat corrupt_part.txt
Oberallg�u
$ grep -P -n '[^\x00-\x7F]' corrupt_part.txt
$ od -h corrupt_part.txt
0000000 624f 7265 6c61 676c 75e4 0a20
0000014
\xe4
예를 들어 ä
확장 ASCII 세트에서도 마찬가지입니다. 그러나 필터링 컨트롤과 인쇄 가능한 문자(ASCII 범위) 위의 grep 명령은 \xe4
이 문자와 일치해야 합니다. 왜 grep 출력이 나오지 않습니까?
답변1
e4 75
실제로는 불법 utf8 시퀀스입니다. utf8에서는 가장 높은 니블이 0xe인 3바이트 시퀀스가 도입됩니다. 두 번째 바이트의 상위 니블(0x7)이 0x8과 0xb 사이에 있지 않기 때문에 시퀀스의 두 번째 바이트는 0x75일 수 없습니다.
이는 iconv가 파일을 유효하지 않은 utf8로 거부하는 이유를 설명합니다. 어쩌면 이미 iso8859-1일까요?
utf8 인코딩 요약은 다음을 참조하세요.위키피디아 테이블
grep 질문의 경우 C/POSIX 로케일을 지정하는 경우 문자가 바이트와 동일할 수 있습니다.
LC_ALL=C grep -P -n '[^\x00-\x7F]' corrupt_part.txt
이전 Ubuntu 시스템, GNU grep 및 en_US.UTF-8 로케일을 사용하는 환경 사용:
$ od -h bytes
0000000 624f 7265 6c61 676c 75e4 0a20
0000014
$ grep -P '[^\x00-\x7F]' bytes | od -h
0000000 624f 7265 6c61 676c 75e4 0a20
0000014
$ LC_ALL=C grep -P '[^\x00-\x7F]' bytes | od -h
0000000 624f 7265 6c61 676c 75e4 0a20
0000014