하나의 파일에서 ASCII가 아닌 모든 문자를 어떻게 제거합니까? 이를 수행하기위한 특정 명령이 있습니까?
grep --colour='auto' -P -n'[^\x00-\x7]' /usr/local/...
나는 이것이 워크 플로우 내에서 문자를 찾는다고 생각하지만 문제가되는 문자의 모든 인스턴스를 어떻게 제거합니까?
cat -v
ASCII represantation으로 표시하십시오. (. 예를 들어 ^G
에 대한 \007
)
하나의 파일에서 ASCII가 아닌 모든 문자를 어떻게 제거합니까? 이를 수행하기위한 특정 명령이 있습니까?
grep --colour='auto' -P -n'[^\x00-\x7]' /usr/local/...
나는 이것이 워크 플로우 내에서 문자를 찾는다고 생각하지만 문제가되는 문자의 모든 인스턴스를 어떻게 제거합니까?
cat -v
ASCII represantation으로 표시하십시오. (. 예를 들어 ^G
에 대한 \007
)
답변:
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:]'
tr
은 텍스트 파일뿐만 아니라 모든 유형의 파일이 될 수 있습니다. awk
반면에 텍스트 파일을 가져옵니다.
gensub()
확장 기능입니다. 을 원하고 gsub(...); print
16 진수 시퀀스 (및 LC_ALL = C) 대신 8 진수를 사용하여 이식 가능하게하십시오.
[^\o0]
POSIX에서 백 슬래시, o 및 0 이외의 문자 sed
(GNU sed를 제외한 모든 구현에서) 와 일치하는 것 입니다. 이는 GNU 의 제한 사항 이 sed
아니라 비 규격 확장이므로 POSIXLY_CORRECT가 환경에있을 때 비활성화됩니다.)