grep은 파일이 바이너리 파일인지 어떻게 확인합니까?

grep은 파일이 바이너리 파일인지 어떻게 확인합니까?

자주 작업하는 대용량 utf-8 텍스트 파일이 있는데 grep최근에 이 grep파일이 바이너리 파일이라고 보고되기 시작했습니다. 을 사용하여 계속 검색할 수 있지만 grep -a파일이 이제 바이너리라고 결정하게 된 변경 사항이 무엇인지 알고 싶습니다.

diff파일이 더 이상 바이너리로 감지되지 않는 지난 달의 복사본이 있지만 20,000줄 이상 다르기 때문에 실용적이지 않습니다 .

file내 파일을 다음으로 식별합니다.

UTF-8 유니코드 영어 텍스트, 긴 줄

문자/줄 등을 어떻게 찾을 수 있나요? 내 파일의 무엇이 이러한 변경을 촉발시켰나요?


유사하고 중복되지 않는 질문19907NUL 가능성을 다루지만 grep -Pc '[\x00-\x1F]'NUL이나 다른 ANSI 제어 문자가 없다고 말합니다.

답변1

파일에 null 문자가 있는 것 같습니다. (보통 ^@ 표시) 텍스트 파일에 다양한 제어 문자(예: 삭제, ^? 등)를 입력했는데 null 문자만으로 grep이 이진 파일로 간주하게 되었습니다. 이것은 grep에 대해서만 테스트되었습니다. 예를 들어 less 및 diff 명령에는 다른 방법이 있을 수 있습니다. 제어 문자는 일반적으로 바이너리 파일을 제외하고는 나타나지 않습니다. 공백 문자는 예외입니다: 줄 바꿈(^M), 탭(^I), 폼 피드(^L), 세로 탭(^K) 및 캐리지 리턴(^J).

그러나 아랍어나 중국어 문자와 같은 외국 문자는 표준 ASCII가 아니며 제어 문자와 혼동될 수 있습니다. 어쩌면 그것이 단지 null 문자인 이유일 수도 있습니다.

텍스트 편집기 vim을 사용하여 텍스트 파일에 제어 문자를 삽입하여 이를 직접 테스트할 수 있습니다. 삽입 모드로 들어가서 Ctrl-V를 누른 다음 제어 문자를 누르세요.

답변2

일반적인 최신 grep 구현에서는 파일이 내부적으로 nul 바이트인 경우에만 파일을 "바이너리"로 선언해야 합니다. 다른 사람들은 괜찮을 것입니다.

나는 당신이 사용하고 있는 grep 구현에 대해 말할 수 없습니다 ...

답변3

mbrlen()에 따른 인코딩 오류로 인해 GNU grep 2.24는 이를 바이너리로 처리합니다.

예를 들어:

export LC_CTYPE='en_US.UTF-8'
printf 'a\x80' | grep 'a'

\x80UTF-8 유니코드 포인트의 첫 번째 바이트가 될 수 없기 때문에 :https://en.wikipedia.org/wiki/UTF-8#설명

이것이 유일한 다른 가능성입니다 NUL.

GNU grep소스 코드 해석은 다음과 같은 결론으로 ​​이어집니다.grep이 파일을 바이너리로 처리하는 이유는 무엇입니까?

관련 정보