[regex] ASCII가 아닌 모든 문자를 어떻게 grep합니까?

매우 큰 XML 파일이 여러 개 있으며 ASCII가 아닌 문자가 포함 된 줄을 찾으려고합니다. 나는 다음을 시도했다.

grep -e "[\x{00FF}-\x{FFFF}]" file.xml

그러나 행에 지정된 범위의 문자가 포함되어 있는지 여부에 관계없이 파일의 모든 행을 반환합니다.

구문이 잘못되었거나 다른 일을하고 있습니까? 나는 또한 시도했다 :

egrep "[\x{00FF}-\x{FFFF}]" file.xml 

(패턴을 둘러싼 작은 따옴표와 큰 따옴표).



답변

다음 명령을 사용할 수 있습니다.

grep --color='auto' -P -n "[\x80-\xFF]" file.xml

그러면 줄 번호가 표시되고 ASCII가 아닌 문자는 빨간색으로 강조 표시됩니다.

일부 시스템에서는 설정에 따라 위의 기능이 작동하지 않으므로 역으로 grep 할 수 있습니다

grep --color='auto' -P -n "[^\x00-\x7F]" file.xml

또한 중요한 비트는 다음과 같은 -P플래그입니다 --perl-regexp. 따라서 패턴을 Perl 정규식으로 해석합니다. 또한 말한다

이것은 매우 실험적이며 grep -P는 구현되지 않은 기능에 대해 경고 할 수 있습니다.


답변

ASCII가 아닌 문자의 바이트 범위에 대해 가정하는 대신 위의 솔루션 대부분이 그러 하듯이 대신 ASCII 문자의 실제 바이트 범위에 대해 명시 적으로 나타내는 것이 IMO보다 약간 좋습니다.

예를 들어 첫 번째 솔루션은 다음과 같습니다.

grep --color='auto' -P -n '[^\x00-\x7F]' file.xml

(기본적으로 16 진 ASCII 범위를 벗어난 모든 문자에 대해 grep : \ x00에서 \ x7F까지)

하지 작업 것이다 마운틴 라이온에 (때문에 BSD의 GREP에서 PCRE 지원의 부족) 과 함께 있지만, pcre브루 통해 설치 한 다음 그냥 잘 작동합니다 :

pcregrep --color='auto' -n '[^\x00-\x7F]' file.xml

누구나 생각할 수있는 장단점?


답변

다음은 나를 위해 작동합니다.

grep -P "[\x80-\xFF]" file.xml

비 ASCII 문자는 0x80에서 시작하여 바이트를 볼 때 0xFF로 이동합니다. Grep (및 제품군)은 멀티 바이트 문자를 단일 엔티티로 병합하여 원하는 정규 표현식 일치를 위해 유니 코드 처리를 수행하지 않습니다. -P내 grep 의 옵션을 사용하면 \xdd캐릭터 클래스에서 이스케이프를 사용하여 원하는 것을 얻을 수 있습니다.


답변

펄에서

perl -ane '{ if(m/[[:^ascii:]]/) { print  } }' fileName > newFile


답변

쉬운 방법은 비 ASCII 문자를 ASCII 문자가 아닌 문자로 정의하는 것입니다.

LC_ALL=C grep '[^ -~]' file.xml

^필요한 경우 탭을 추가하십시오 .

설정 LC_COLLATE=C하면 많은 로케일에서 문자 범위의 의미에 대한 놀라운 놀라움을 피할 수 있습니다. LC_CTYPE=C1 바이트 문자를 일치시키기 위해 설정 이 필요합니다. 그렇지 않으면 명령이 현재 인코딩에서 유효하지 않은 바이트 시퀀스를 놓치게됩니다. 설정 LC_ALL=C은 로케일에 따른 영향을 완전히 피합니다.


답변

허용 된 답변에서 grep 검색과 완전히 다른 결과를 얻은 다른 변형이 [\x80-\xFF]있습니다. 아마도 비 ASCII 문자를 찾는 것이 누군가에게 유용 할 것입니다.

grep --color='auto' -P -n "[^[:ascii:]]" myfile.txt

참고 : 내 컴퓨터의 grep (Mac)에는 -P옵션 brew install grepggrep없으므로을 대신하여 위의 전화를 걸었습니다 grep.


답변

다음 코드가 작동합니다.

find /tmp | perl -ne 'print if /[^[:ascii:]]/'

대체 /tmp당신은을 통해 검색 할 디렉토리의 이름으로.