워크 플로우 (파일)에서 ASCII가 아닌 모든 문자 제거 하나의 파일에서 ASCII가

하나의 파일에서 ASCII가 아닌 모든 문자를 어떻게 제거합니까? 이를 수행하기위한 특정 명령이 있습니까?

grep --colour='auto' -P -n'[^\x00-\x7]' /usr/local/...

나는 이것이 워크 플로우 내에서 문자를 찾는다고 생각하지만 문제가되는 문자의 모든 인스턴스를 어떻게 제거합니까?



답변

ASCII 문자는 0에서 177 (8 진수) 사이의 문자입니다 .

파일에서이 범위 밖의 문자를 삭제하려면

LC_ALL=C tr -dc '\0-\177' <file >newfile

tr명령은 단일 문자 에서 작동하는 유틸리티 로 다른 단일 문자로 대체하거나 (음역) 삭제하거나 동일한 문자의 실행을 단일 문자로 압축합니다.

위의 명령은 file에서 수정 된 내용을 읽고 씁니다 newfile. -d에 옵션 tr유틸리티 삭제 자 (대신 그들을 음역의) 차종, 그리고 -c그것은 주어진 간격 (대신 내부의) 외부의 문자를 고려한다.

LC_ALL=C모든 바이트 값이 유효한 문자를 구성하는지 확인하십시오. tr그렇지 않으면 로케일의 문자 인코딩에서 유효한 문자를 형성하지 않는 일련의 바이트를 발견하면 일부 구현이 중단됩니다.


원본 파일을 수정 된 파일로 바꾸려면

LC_ALL=C tr -dc '\0-\177' <file >newfile &&
mv newfile file

새 파일의 이름이 tr성공적으로 완료된 후 이전 파일의 이름으로 바뀝니다 . 경우 tr성공적으로 완료되지 않은 원래 파일을 읽을 수 없습니다 또는 새 파일에 쓸 수 있기 때문에, 하나, 원본 파일은 변경되지 않습니다.

또는 원본 파일의 메타 데이터 (권한 등)를 최대한 보존하려면

cp file tmpfile &&
LC_ALL=C tr -dc '\0-\177' <tmpfile >file &&
rm tmpfile

답변

perl

perl -pi -e 's/[^[:ascii:]]//g'

답변

필요한 것이 정규 표현식이라면 [\x00-\x7F]여러 유틸리티에 적용 할 수 있습니다.

<file LC_ALL=C   sed   's/[^\o0-\o177]//g'      # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C   awk   '{gsub(/[^\0-\177]/,"");print}'
<file            perl  -pe 's/[^[:ascii:]]//g;'
<file LC_ALL=C   tr    -dc '\0-\177'

sed, awk 및 perl은 Unix에 정의 된 “텍스트 파일”을 기대합니다. 이 경우 모든 것이 잘 작동합니다. 그러나 특히 awk는 소스 파일에 존재하는지 여부에 관계없이 후행 줄 바꿈을 추가합니다 (printf를 사용하면 입력의 모든 줄 바꿈이 제거됩니다). tr은 모든 파일 형식에서 작동하도록 설계되었습니다. 그러나 NUL ( \0)은 POSIX 텍스트 파일 에서 유효한 문자가 아니므 로 피해야합니다.

줄에 NUL 문자가 없습니다 …

실제로 많은 제어 문자는 특정 조건에서 다른 문제를 발생시킵니다.
그래서 아마도[\x07-\x0d\x20-\x7e]

<file LC_ALL=C   sed   's/[^\o007-\o015\o040-\o176]//g'            # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C   awk   '{gsub(/[^\0-\15\40-\176]/,"");print}'
<file            perl  -pe 's/[^\x{7}-\x{d}\x{20}-\x{7e}]//g;'
<file LC_ALL=C   tr    -dc '\7-\15\40-\176'

7-13 범위 (10 진수)는 \a\b\t\n\v\f\r(순서대로)입니다.
비슷한 (아마도 이식성이 좋은) 범위는 [^[:space:][:print:]] (similar because it doesn't include\ a \ b` –bell and backspace–) 로 쓸 수 있습니다 .

<file LC_ALL=C   sed   's/[^[:space:][:print:]]//g'  # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C   awk   '{gsub(/[^[:space:][:print:]]/,"");print}'
<file            perl   -pe 's/[^[:space:][:print:]]//g;'
<file LC_ALL=C   tr     -dc '[:space:][:print:]'

관련 :
정규식 ASCII 문자
Perl 솔루션
Posix 텍스트 파일