
sed 파일을 사용하여 파일을 전처리하려고 했는데 sed 출력의 형식이 변경되는 것 같습니다. 어떻게 피해야 합니까?
file A.txt
A.txt UTF-8 Unicode English text, with very long lines
sed -f process.sed < A.txt > B.txt
head -2 process.sed
#!/bin/sed -f
s/[‘’"“”•·・、。《》™®\.★☆]\\[a-z\-]\+ //g
file B.txt
Non-ISO extended-ASCII English text, with very long lines, with LF, NEL line terminators
B.txt는 UTF-8로 인코딩되지 않았기 때문에 다음 처리를 할 수 없습니다.
vim B.txt
è·¯æ<98><93>æ<96>¯ Âç½<97>å¾·é<87><8c>æ ¼æ<96>¯ //è·¯æ<98><93>æ<96>¯Â·ç½<97>å¾·é<87><8c>æ ¼æ<96>¯ ]
답변1
문제는 sed의 정규 표현식 엔진이 입력 파일이나 […]
일치 항목을 유니코드 문자 목록으로 보지 않는다는 것입니다. 대신에 각각을 여러 개의 독립 바이트로 간주합니다. 예를 들어 •
3바이트로 보고 \xe2 \x80 \xa2
각각을 개별적으로 일치시키려고 시도합니다 [ \xe2 \x80 \x98 \xe2 \x80 \x99 \x22 \xe2 \x80 ... ]
.
따라서 게시물에 표시된 예에서 정규식은 각 구두점 문자의 마지막 바이트만 일치하고 삭제하고 나머지 2개는 그대로 둡니다. 이것이 잘못된(UTF-8이 아닌) 출력 파일을 제공하는 것입니다.
GNU sed(4.5에서 테스트됨)를 사용하면 다음을 확인하여 이 문제를 피할 수 있습니다.시스템 로케일($LANG 또는 최소한 $LC_CTYPE 환경 변수)는 UTF-8 호환 로케일로 설정됩니다. 예를 들어:
$ 내보내기 LANG='C' $ echo ''테스트' '테스트'' | sed 's/[“”•]/X/g' XX�테스트XX� XXX테스트XXX $ echo '•_test' | sed 's/[•‡]_/X_/' ��X_테스트 $ 내보내기 LANG='en_US.UTF-8' $ echo ''테스트' '테스트'' | sed 's/[“”•]/X/g' '테스트' XtestX $ echo '•_test' | sed 's/[•‡]_/X_/' X_테스트
(로케일 언어는 중요하지 않습니다.어느UTF-8 로케일이 작동합니다.)
이것이 효과가 없다면 […]
완전히 사용 하지 말고 다중 문자 대안이며 해당 문자가 어떻게 해석되는지에 관계없이 작동하는 \(…\|…\|…\)
(또는 sed -r에서)을 사용하십시오.(…|…|…)
$ 내보내기 LANG='C' $ echo ''테스트' '테스트'' | sed 's/\(“\|”\|•\)/X/g' '테스트' XtestX $ echo '•_test' | sed 's/\(•\|‡\)_/X_/' X_테스트