재귀 grep은 일부 파일의 일치 항목을 나열하지 않습니다.
특정 패턴을 포함하는 스크립트를 찾기 위해 GNU grep 3.4를 사용하고 있습니다. 이를 위해 이렇게 grep
재귀 적으로 호출합니다.
grep -rin . -e "pattern"
패턴은 정규식이 아닌 단어 일뿐입니다. 이상한 점은 출력이 문자열을 확실히 포함하는 일부 파일의 발생을 나열하지 않는다는 것입니다.
이 파일을 열고 vim
사용하여 검색 을 시도 /pattern
했으며 패턴을 찾습니다. 인코딩은 표시되는 vim
등 [dos:utf-8:]
. 줄을 복사하여 새 파일에 쓰면 위의 grep
명령이 올바르게 나열합니다.
grep
원본 파일이 나열 되지 않는 이유는 무엇 입니까?
답변
Grep (또는 적어도 이전 버전)는 UTF8을 이해하지 못합니다. 따라서 구성된 문자, 하이픈 포인트 또는 기타 보이지 않는 데이터는 grep을 방해 할 수 있습니다.
Grep은 다음 값의 영향도받습니다. $LC_ALL, $LC_CTYPE 및 $ LANG.
vim을 사용하여 grep이 찾지 못한 단어 주위에 몇 줄을 저장 한 다음 그 작은 예제 파일의 hexdump를 만드십시오. grep이 실패한 이유를 알게 될 것입니다.
당신은 또한 (정력 명령을 사용할 수 있습니다 ga
, g8
문자를 검사 등)하지만 헥스 덤프 명확하게 할 수있다
나는 문제를 발견했습니다 (다른 답변의 도움으로). 'grep'파일은 실제로 utf-8
인코딩 되지 않았지만 utf-16be
. 나는 hexdump (@RedGrittyBrick에 대한 크레딧)를 사용하여 이것을 배웠습니다.
hd file_for_which_grep_works_as_expected.txt
양보
00000000 20 20 20 20 50 61 74 74 65 72 6e 0a | Pattern.|
0000000c
이므로
hd file_for_which_grep_fails.txt
반환
00000000 fe ff 00 50 00 61 00 74 00 74 00 65 00 72 00 6e |...P.a.t.t.e.r.n|
00000010 00 0a |..|
00000012
따라서 인코딩을 다시 확인하십시오.
file -i file_for_which_grep_fails.txt
으로 식별했습니다 text/plain; charset=utf-16be
.
에 utf-8
표시된 파일vim
이 실제로 파일 인코딩이 아닌 버퍼 인코딩 이라는 것을 인식하지 못했습니다 . 실행 에 도 올바르게 표시 (여기:set fileencoding
vim
fileencoding=utf-16
https://superuser.com/a/28783/1210682).
따라서 문제는 인코딩 된 파일에서 grep
작동하지 않는다는 것입니다 utf-16
. 이것은 이미 여기에 설명되어 있습니다.https://superuser.com/a/231471/1210682. 그러나, 변환의 치료 utf-16
에 파일을 utf-8
하기 전에 grep
내가 재귀를 사용할 때 작동하지 않습니다 나는 파일이있을 수있는 사전에 알고하지 않는 한 utf-8
어느 utf-16
와 많은 파일을 통해 오전 검색.
다른 솔루션이 있습니다. 그 중 두 가지를 여기서 간단히 설명하겠습니다.
빠른 - 및 - 더러운 나를 위해 일한 솔루션은 일치합니다 하나를 포함하는 검색 패턴을 확장했다
utf-16
버전을 두 패턴 중 하나를 검색을 :grep -riPa . -e "pattern|p.a.t.t.e.r.n."
물론 이것은 가능한 패턴 측면에서 매우 제한적입니다.
grep
likeugrep
또는ripgrep
that (무엇보다도)에 대한 대안이utf-16
파일 을 처리 할 수 있습니다 .ripgrep
18.04의 표준 Ubuntu 패키지 리포지토리에서 사용할 수있는 것을 사용 하게되었습니다.rg -i "pattern"
여기에 대안에 대한 훌륭한 토론이 있습니다. https://stackoverflow.com/questions/3752913/grepping-binary-files-and-utf16, 그들 중에는 검색 패턴을로 변환하고이를로 utf-16
공급 하려는 흥미로운 접근 방식 이 grep
있습니다. 그러나 나는 그것을 작동시킬 수 없었다.