Perl 및 sed에서 인쇄할 수 없는 문자 바꾸기

Perl 및 sed에서 인쇄할 수 없는 문자 바꾸기

파일에서 인쇄할 수 없는 일부 문자를 공백으로 바꿔야 합니다.

0x00특히 (TAB), (개행), (CR) 0x1F을 제외한 에서 까지의 모든 문자0x090x0A0x0D

지금까지는 역할만 바꾸면 됐어요 0x00. 이전 OS는 AIX(GNU 명령 없음)였기 때문에 사용할 수 없었습니다 sed(글쎄, 사용할 수 있었지만 몇 가지 제한 사항이 있었습니다). 그래서 다음 명령을 찾았 perl는데 예상대로 작동합니다.

perl -p -e 's/\x0/ /g' $FILE_IN > $FILE_OUT 

sed이제 저는 Linux를 사용하고 있으므로 명령을 사용할 수 있기를 원합니다 .

내 질문:

  • 이 명령이 이러한 문자를 바꾸는 데 적합합니까? 이것을 시도했는데 작동하는 것 같지만 다음 사항을 확인하고 싶습니다.

    perl -p -e 's/[\x00-\x08\x0B\x0C\x0E-\x1F]/ /g' $FILE_IN > $FILE_OUT  
    
  • 나는 perl -p그것이 작동한다고 생각합니다 sed. 그러면 이전 명령은 작동하지만(적어도 실패하지 않고) 다음 명령은 작동하지 않는 이유는 무엇입니까?

    sed -e 's/[\x00-\x08\x0B\x0C\x0E-\x1F]/ /g' $FILE_IN > $FILE_OUT   
    

    그것은 나에게 말한다 :

    sed: -e 표현식 #1, 문자 34: 잘못된 정렬 문자

답변1

일반적인 작업은 다음과 같습니다 tr.

LC_ALL=C tr '\0-\10\13\14\16-\37' '[ *]' < in > out

sed귀하의 경우에는 범위가 귀하의 로케일에서 이해되지 않기 때문에 작동하지 않습니다 . 문자 대신 바이트 값을 사용하고 순서가 해당 바이트의 숫자 값을 기반으로 하는 경우 가장 좋은 옵션은 다음과 같습니다.C 로캘 사용. 귀하의 코드는 LC_ALL=CGNU 와 함께 사용될 수 있지만 여기서는 sed사용하는 것이 sed약간 perl과잉입니다(그리고 메소드는 \xXX구현 측면에서 이식성이 없지만 sedtr메소드는 POSIX입니다).

해당 지역의 아이디어를 신뢰할 수도 있습니다.인쇄 가능문자는 다음과 같습니다

tr -c '[:print:]\t\r\n' '[ *]'

그러나 GNU tr(일반적으로 Linux 기반 시스템에서 발견됨)의 경우 문자가 단일 바이트(일반적으로 UTF-8이 아님)인 로케일에서만 작동합니다.

C 로케일에서는 DEL(0x7f) 및 위의 모든 바이트 값(ASCII 아님)도 제외됩니다.

UTF-8 로케일에서는 GNU가 가지고 있는 문제를 sed겪지 않는 GNU를 사용할 수 있습니다:tr

sed 's/[^[:print:]\r\t]/ /g' < in > out

(이것은 표준이 \r아니며 \tGNU는 환경에 있는 경우 이를 인식하지 못합니다 sed(백슬래시로 처리하고 r 및 t는 POSIX에서 요구하는 세트의 일부입니다).POSIXLY_CORRECT

그러나 유효한 문자(있는 경우)를 형성하지 않는 바이트는 변환하지 않습니다.

답변2

libnotify를 통해 알림을 보내려고 하는데, 내용에 인쇄할 수 없는 문자가 포함될 수 있습니다. 기존 솔루션은 저에게 잘 작동하지 않습니다( tr유효한 문자 허용 목록을 사용하지만 멀티바이트 문자를 제거함).

이는 유효하며 둘 다 통과합니다.

관련 정보