매우 큰 텍스트 파일에서 외국어 및 기타 키보드가 아닌 문자를 제거하기 위해 SED 명령을 사용하고 있습니다.
예:
sed 's/[^a-zA-Z0-9]//g'
위 명령은 내가 원하는 것과 가까운 영숫자 문자만 포함하는 모든 줄을 유지합니다. 문제는 !@#$% 등과 같은 일반적인 기호가 포함된 줄도 제거한다는 것입니다. 나는 그것들을 간직하고 싶다. !-)와 같은 금괴 명령을 검색해 보았습니다. 하지만 비슷한 것을 찾을 수 없습니다.
그렇다면 목록에서 아랍어, 러시아어 및 입력할 수 없는 문자를 필터링하는 방법은 무엇입니까? (이상적으로는 캐릭터에만 핵폭탄을 쏘고 싶지 않고 캐릭터가 발견된 행 전체에 핵폭탄을 쏘고 싶습니다.)
답변1
Kusalananda와 같은 클래스를 사용하는 것 외에도 유니코드를 기반으로 자신만의 범위를 만들 수 있습니다. 확인하다이것은 유니콜드 테이블을 의미합니다.마음에 드는 캐릭터를 찾아보세요. PCRE의 경우 "표준" 문자 + TAB에 가능한 방법은 다음과 같습니다.
grep -P '^[\x{0020}-\x{007e}\x{0008}]{1,}$' file
\x{000A}
grep
줄당 기능(표준 모드) 으로 인해 개행 문자는 제어 문자로 포함되지 않습니다. MS 스타일 개행 문자가 영향을 받고 \x{000d}\x{000a}
개행 문자에 사용된다는 점을 고려하세요!
답변2
텍스트에서 ASCII가 아닌 문자를 제거하려면 tr
다음과 같은 방법을 사용하는 것이 좋습니다.
LC_ALL=C tr -d -c '[:print:][:cntrl:]' <file.in >file.out
두 POSIX 문자 클래스는 [:print:]
함께 [:cntrl:]
ASCII 범위의 모든 문자를 포괄하므로 이에 대한 보완, 즉 모든 비ASCII 문자를 고려해야 -c
합니다 . tr
우리는 이 보완 문자를 제거할 -d
것을 요청합니다 .tr
문자 클래스가 ASCII 범위 32에서 126 사이의 문자만 일치 하도록 (또는 ) LC_ALL
로 설정했습니다 . 그렇지 않으면 로케일의 인쇄 가능한 문자와 일치할 수 있습니다(예: ) . 이 클래스는 0~31 및 127 범위의 문자와 일치합니다. 를 사용하면 이 두 클래스가 함께 ASCII 문자인 0~127을 포함합니다.C
POSIX
[:print:]
ä
[:cntrl:]
LC_ALL=C
ASCII가 아닌 문자가 포함된 전체 줄을 삭제하려면:
LC_ALL=C grep -v '[^[:print:][:cntrl:]]' <file.in >file.out
이 표현식은 [^[:print:][:cntrl:]]
ASCII가 아닌 단일 문자와 일치합니다. -v
쿼리를 사용하여 grep
모든 행을 추출합니다.아니요ASCII가 아닌 문자를 포함하지 않는 줄을 추출하는 이 표현식과 일치합니다.
이 두 명령은 다음을 사용하여 수행할 수도 있습니다 sed
.
ASCII가 아닌 문자를 제거합니다.
LC_ALL=C sed 's/[^[:print:][:cntrl:]]//g' <file.in >file.out
ASCII가 아닌 문자가 포함된 줄을 삭제합니다.
LC_ALL=C sed '/[^[:print:][:cntrl:]]/d' <file.in >file.out
Stéphane이 지적했듯이댓글에서, 위 명령은 ASCII 문자만 포함하는 텍스트를 반환합니다.또는 최소한 ASCII로 인코딩된 문자(파일 인코딩에 따라 다릅니다.)
완전히 다른 접근 방식은 다음을 사용하는 것입니다 iconv
.
iconv -c -t ascii file.in >file.out
그러면 파일이 ASCII 인코딩으로 변환되어 변환할 수 없는 모든 문자(줄 아님)가 자동으로 제거됩니다.