파일에서 ASCII가 아닌 문자를 모두 제거하는 방법은 무엇입니까? 이를 수행하는 특정 명령이 있습니까?
grep --colour='auto' -P -n'[^\x00-\x7]' /usr/local/...
이렇게 하면 작업 흐름에서 캐릭터를 찾을 수 있다고 생각합니다. 하지만 관련 캐릭터의 모든 인스턴스를 어떻게 제거합니까?
답변1
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
답변2
그리고perl
perl -pi -e 's/[^[:ascii:]]//g'
답변3
정규식만 필요한 경우: [\x00-\x7F]
.
여러 유틸리티에 적용할 수 있습니다.
<file LC_ALL=C sed 's/[^\o0-\o177]//g' # GNU sed not POSIXLY_CORRECT
<file LC_ALL=C awk '{gsub(/[^\0-\177]/,"");print}'
<file perl -pe 's/[^[:ascii:]]//g;'
<file tr -dc '\0-\177'
sed, awk 및 perl을 이해하려면 Unix에 정의된 "텍스트 파일"이 필요합니다. 이 경우 모든 것이 잘 작동합니다. 그러나 구체적으로 awk는 소스 파일에 존재하는지 여부에 관계없이 후행 줄 바꿈을 추가합니다(print를 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 tr -dc '\7-\15\40-\176'
7-13(십진수) 범위는 \a\b\t\n\v\f\r
(순서대로)입니다.
유사한(더 이식성이 높은) 범위는 [^[:space:][:print:]] (similar because it doesn't include
\a\b` --bell 및 백스페이스--)로 작성할 수 있습니다.
<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 tr -dc '[:space:][:print:]'