UTF-8 파일에서 BOM을 제거하려면 어떻게해야합니까?


63

BOM이있는 UTF-8 인코딩 파일이 있으며 BOM을 제거하고 싶습니다. 파일에서 BOM을 제거하는 Linux 명령 행 도구가 있습니까?

$ file test.xml
test.xml:  XML 1.0 document, UTF-8 Unicode (with BOM) text, with very long lines


1
난 그냥 몇 달 전에 것을 할 수있는 farily 간단한 도구를 만들었어요 : oskog97.com/read/?path=/small-scripts/killbom&referer=/...는 / usr / 지방 / 빈 경우에 뭔가를 설치하는 가치가있을 수도 있습니다 BOM이있는 많은 UTF-8 인코딩 파일이 있습니다.
Oskar Skog

답변:


76

파일에 UTF-8 BOM이 포함되어 있는지 확실하지 않은 경우, GNU 구현으로 가정 sed하면 BOM이 존재하는 경우 BOM을 제거하거나 그렇지 않은 경우 변경하지 않습니다.

sed '1s/^\xEF\xBB\xBF//' < orig.txt > new.txt

다음 -i옵션으로 기존 파일을 덮어 쓸 수도 있습니다.

sed -i '1s/^\xEF\xBB\xBF//' orig.txt

4
이것은 utf8 로케일에서는 작동하지 않지만 c 또는 posix에 로케일 대체를 추가하면 항상 작동합니다.
hildred

3
@hildred 나는 en_US.UTF-8로케일로 테스트 했으며 효과가있었습니다. 언제 실패할까요?
m13r

2
@ m13r, sed 및 compile 옵션의 버전에 따라 다릅니다. 실패한 경우, 유니 코드 문자 클래스가있는 매우 새로운 버전의 sed는 3 바이트 시퀀스를 3 개의 문자 시퀀스와 일치하지 않는 단일 문자로 가져옵니다. 그러나 이러한 경우 16 비트 문자 일치를 수행 할 수 있습니다. 그러나 이것은 새로운 기능이며 보편적으로 존재하지는 않습니다. 테스트하려면 최신 버전을 컴파일하는 것이 좋습니다.
hildred

4
유니 코드 가능 sed로 작동하도록 수정하려면 LC_ALL = C sed '1s / ^ \ xEF \ xBB \ xBF //'
Joshua

@CSM은 좋지만 특별한 경우에는 작동하지 않습니다. Bevore : -<U+FEFF>\chapter{xxx}After : +\chapter{xxx}^M 설명 : 라텍스 파일에서 오타에 MS 단어를 사용합니다. 리눅스에서 라텍스는 언급 된 오류를 보이고있다. git 시스템에서 출력됩니다. 이 특별한 경우를 잡기 위해 표현을 어떻게 바꿀 수 있습니까?
Cutton Eye

64

BOM은 UTF-8에서 의미가 없습니다. 이들은 일반적으로 Microsoft OS의 가짜 소프트웨어에 의해 실수로 추가됩니다.

dos2unix 그것을 제거하고 Windows 텍스트 파일의 다른 특성을 돌볼 것입니다.

dos2unix test.xml

17
UTF-8로 인코딩 된 BOM은 의미가 없지만 믿거 나 말거나 UTF-8을 다른 8 비트 인코딩과 구별하는 데 도움이된다고 생각하는 사람들이 많이 있습니다. 맛의 문제입니다. Windows 메모장은 의도적으로 BOM을 추가합니다.
Johan Myréen

17
문맥이 그것을 제거하는 방법에 대한 질문 일 때, 그것이 의미가 있든 없든, 그것은 중요합니까? Wikipedia에 따르면 메모장은 파일을 UTF-8로 인식하기 위해 BOM이 필요하며 Google 문서는 파일을 텍스트로 내보내는 동안 파일을 추가합니다. 나는 그들이 모두 실수로 그것을 의심 합니다.
ilkkachu

의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
terdon

1
줄 끝을 변환하지 않고로 BOM을 제거하는 방법이 dos2unix있습니까?
m13r

2
@ m13r 그런 다음 이 답변에서 sed 스크립트를 사용하십시오 . 그러면 bom 만 제거되고 (있는 경우) 다른 것은 변경되지 않습니다.
Arrow

25

다음 tail명령 을 사용하여 파일에서 BOM을 제거 할 수 있습니다 .

tail -c +4 withBOM.txt > withoutBOM.txt

2
왜 4입니까? BOM에는 3 바이트가 있습니다.
deviantfan

10
@deviantfan 그렇기 때문에 건너 뛰려면 4 번째 바이트부터 시작해야합니다.
Stéphane Chazelas

9
tail1 기반 인덱싱을 사용하고 있습니까?! 이런 씨발!
코드 InChaos

5
@CodesInChaos, tail -c -1또는은 tail -c 1(어떤 tail일반적으로 사용된다)의 마지막 바이트로 시작하는 컨텐츠 인 tail -c +1첫번째 바이트부터 시작. tail -c 0/ tail -c +0그게 훨씬 더 직관적이 될 것이기 때문.
Stéphane Chazelas

2
@deviantfan : (dd bs=1 count=3 of=/dev/null; cat) <input >output. 또는 (head -c3 >/dev/null; cat)UTF8 또는 기타 비 싱글 바이트 로케일에서도 GNU를 사용합니다 . GNU 헤드는 'char'= byte를 수행합니다.
dave_thompson_085

20

VIM 사용

  1. VIM에서 파일 열기 :

    vi text.xml
    
  2. BOM 인코딩을 제거하십시오.

    :set nobomb
    
  3. 저장하고 종료하십시오 :

    :wq
    

이상하게도 Mac에서 vim 8을 사용하면 Excel에서 만든 csv utf-8 파일이 있으며로 시작 <feff>하지만 :set nobomb수정하거나 제거하지는 않습니다.
dlamblin

5

당신이 사용할 수있는

LANG=C LC_ALL=C sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- filename

파일의 시작 부분에서 바이트 순서 표시를 제거하고 CR LF 개행을 LF로만 변환합니다. 이 LANG=C LC_ALL=C명령은 쉘이 명령을 기본 C 로케일 (기본 POSIX 로케일이라고도 함)에서 실행하도록하는데, 여기서 바이트 순서 마크를 형성하는 3 바이트는 바이트로 처리됩니다. -i나오지하는 옵션에 적절한 의미한다. 을 사용하는 경우 -i.oldsed는 원본 파일을으로 저장 filename.old하고 새 파일 (있는 경우 수정 사항이있는 경우)을으로 저장 filename합니다.


나는 개인적으로 이것을 이것을 좋아합니다 ~/bin/fix-ms. 예를 들어

#!/bin/dash
export LANG=C LC_ALL=C
if [ $# -gt 0 ]; then
    for FILE in "$@" ; do
        sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$FILE" || exit 1
    done
else
    exec sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//'
fi

모든 C 소스 파일과 헤더 (예 : MS-DOS 시대의 오래된 코드)를 말하기 위해 이것을 적용 해야하는 경우, 나는 단지 실행합니다.

find . -name '*.[CHch]' -print0 | xargs -r0 ~/bin/ms-fix

또는 수정하지 않고 그러한 파일을보고 싶다면 실행할 수 있습니다.

~/bin/ms-fix < filename | less

<U+FEFF>UTF-8 터미널에서 못 생겼 습니다.


왜 간단하지 sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@"않습니까?
Stéphane Chazelas

@ StéphaneChazelas : 대체에 문제가있는 경우 스크립트가 즉시 종료되기를 원합니다 sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@". 종료 코드를 리턴하지만 종료하기 전에 인수 목록에 나열된 모든 파일을 처리합니다.
공칭 동물

@ StéphaneChazelas : --파일 이름 이전은 물론 중요합니다. 파일 이름없이 대시로 시작하는 파일 이름은 sed에 의해 옵션으로 간주 될 수 있습니다. 나는 그것들을 나의 대답으로 편집했다. 알림 주셔서 감사합니다!
공칭 동물

0

최근에 임의의 UTF-8 인코딩 파일에서 BOM을 추가하거나 제거하는이 작은 명령 줄 도구를 찾았습니다. UTF BOM 유틸리티 ( github의 새 링크 )

약간의 단점은 일반 C ++ 소스 코드 만 다운로드 할 수 있다는 것입니다. makefile ( 예 : CMake 사용 )을 작성하고 직접 컴파일해야합니다.이 페이지에는 바이너리가 제공되지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.