awk를 사용하여 바이트 순서 표시 제거


105

BOMawk 을 제거 하는 스크립트 (아마 한 줄짜리)는 어떻게 생겼습니까?

사양:

  • 첫 번째 ( NR > 1) 이후의 모든 행을 인쇄합니다.
  • 첫 번째 줄 : #FE #FF또는로 시작하는 경우 #FF #FE제거하고 나머지를 인쇄합니다.

답변:


114

이 시도:

awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE

첫 번째 레코드 (행)에서 BOM 문자를 제거하십시오. 모든 기록을 인쇄합니다.

또는 awk의 기본 작업이 레코드를 인쇄하는 것이라는 지식을 사용하면 약간 더 짧습니다.

awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE

1 항상 참으로 평가되는 가장 짧은 조건이므로 각 레코드가 인쇄됩니다.

즐겨!

-부록-

유니 코드 BOM (Byte Order Mark) FAQ 에는 각 인코딩에 대한 정확한 BOM 바이트가 나열된 다음 표가 포함되어 있습니다.

Bytes         |  Encoding Form
--------------------------------------
00 00 FE FF   |  UTF-32, big-endian
FF FE 00 00   |  UTF-32, little-endian
FE FF         |  UTF-16, big-endian
FF FE         |  UTF-16, little-endian
EF BB BF      |  UTF-8

따라서 위 표에서 BOM 바이트에 \xef\xbb\xbf해당하는 방법을 확인할 수 있습니다 EF BB BF UTF-8.


1
sub 문 중간의 점이 너무 많은 것 같습니다 (적어도 내 awk는 그것에 대해 불평합니다). 이 외에도 정확히 내가 검색 한 것입니다. 감사합니다!
Boldewyn

5
그러나이 솔루션 은 UTF-8로 인코딩 된 파일에 대해서만 작동 합니다. UTF-16과 같은 기타의 경우 해당 BOM 표현은 Wikipedia를 참조하십시오. en.wikipedia.org/wiki/Byte_order_mark
Boldewyn

2
따라서 : awk '{if(NR==1)sub(/^\xef\xbb\xbf/,"");print}' INFILE > OUTFILEINFILE과 OUTFILE이 다른지 확인하십시오!
Steve Clay

1
사용한 경우 perl -i.orig -pe 's/^\x{FFFE}//' badfile인코딩을 위해 PERL_UNICODE 및 / 또는 PERLIO 환경 변수를 사용할 수 있습니다. PERL_UNICODE = SD는 UTF-8에서 작동합니다. 다른 사람들에게는 PERLIO가 필요합니다.
tchrist

1
조금 더 짧은 버전 일 수도 있습니다.awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1'
TrueY

122

GNU 사용 sed(Linux 또는 Cygwin) :

# Removing BOM from all text files in current directory:
sed -i '1 s/^\xef\xbb\xbf//' *.txt

FreeBSD에서 :

sed -i .bak '1 s/^\xef\xbb\xbf//' *.txt

GNU 또는 FreeBSD 사용의 장점 sed: -i매개 변수는 "제자리"를 의미하며 리디렉션이나 이상한 속임수없이 파일을 업데이트합니다.

Mac :

awk다른 답변 의이 솔루션은 작동 하지만 sed위 의 명령은 작동하지 않습니다. 적어도 Mac (Sierra) sed문서에서는 16 진수 이스케이프 ala 지원에 대해 언급하지 않습니다 \xef.

moreutils 에서 sponge도구 로 파이핑하여 모든 프로그램에서 유사한 트릭을 얻을 수 있습니다 .

awk '…' INFILE | sponge INFILE

5
두 번째 명령을 Mac OS X에서 정확하게 시도했는데 결과는 "성공"이었지만 실제로는 대체가 발생하지 않았습니다.
Trejkaz

1
이러한 명령 이 가능한 바이트 순서 표시 중 하나 인 특정 바이트 시퀀스를 대체한다는 점은 주목할 가치가 있습니다. 파일에 다른 BOM 시퀀스가있을 수 있습니다. (내가 Mac을 사용하지 않는 한, 그 이외의 도움이되지 수)
데닐손 Sá 마이 아에게

3
0xef 0xbb 0xbf를 BOM으로 사용하는 파일에 대해 OS X에서 두 번째 명령을 시도했을 때 실제로 대체를 수행하지 않았습니다.
John Wiseman

OSX에서는 다음과 같이 perl을 통해서만이 작업을 수행 할 수 있습니다. stackoverflow.com/a/9101056/2063546
Ian

OS X El Capitan 10.11.6에서는 작동하지 않지만 공식 답변 stackoverflow.com/a/1068700/9636 은 정상적으로 작동합니다.
Heath Borders

42

어색하지는 않지만 더 간단합니다.

tail -c +4 UTF8 > UTF8.nobom

BOM을 확인하려면 :

hd -n 3 UTF8

BOM이있는 경우 다음이 표시됩니다. 00000000 ef bb bf ...


6
BOM은 UTF-16의 경우 2 바이트이고 UTF-32의 경우 4 바이트이며 물론 처음에 UTF-8로 된 비즈니스는 없습니다.
tchrist

2
@KarolyHorvath 네, 정확합니다. 사용하지 않는 것이 좋습니다. 그것은 물건을 깨뜨립니다. 인코딩은 더 높은 수준의 프로토콜에서 지정해야합니다.
tchrist

1
@tchrist : 당신은 깨진 물건을 부수는 것을 의미합니까? :) 적절한 앱이 해당 BOM을 처리 할 수 ​​있어야합니다.
Karoly Horvath

7
@KarolyHorvath I 평균이 중단 많은 프로그램을 . 내가 말한 거 아니야? UTF-16 또는 UTF-32 인코딩으로 스트림을 열면 디코더가 BOM을 계산하지 않음을 인식합니다. UTF-8을 사용할 때 디코더는 BOM을 데이터로 표시합니다. 무수한 프로그램의 구문 오류입니다. Java의 디코더조차도 이러한 방식으로 작동합니다. BY DESIGN! UTF-8 파일의 BOM이 잘못 배치되고 엉덩이에 고통 이 있습니다. 오류입니다! 그들은 많은 것을 깨뜨립니다. 그냥 cat file1.utf8 file2.utf8 file3.utf3 > allfiles.utf8부서 질 것입니다. UTF-8에서 BOM을 사용하지 마십시오. 기간.
tchrist

6
hdOS X (10.8.2 기준)에서는 사용할 수 없으므로 UTF-8 BOM을 확인하려면 다음을 사용할 수 있습니다 head -c 3 file | od -t x1..
mklement0

21

CRLF 줄 끝을 LF로 변환하는 것 외에도 dos2unixBOM도 제거합니다.

dos2unix *.txt

dos2unix 또한 BOM이있는 UTF-16 파일 (BOM이없는 UTF-16 파일은 아님)을 BOM이없는 UTF-8로 변환합니다.

$ printf '\ufeffä\n'|iconv -f utf-8 -t utf-16be>bom-utf16be
$ printf '\ufeffä\n'|iconv -f utf-8 -t utf-16le>bom-utf16le
$ printf '\ufeffä\n'>bom-utf8
$ printf 'ä\n'|iconv -f utf-8 -t utf-16be>utf16be
$ printf 'ä\n'|iconv -f utf-8 -t utf-16le>utf16le
$ printf 'ä\n'>utf8
$ for f in *;do printf '%11s %s\n' $f $(xxd -p $f);done
bom-utf16be feff00e4000a
bom-utf16le fffee4000a00
   bom-utf8 efbbbfc3a40a
    utf16be 00e4000a
    utf16le e4000a00
       utf8 c3a40a
$ dos2unix -q *
$ for f in *;do printf '%11s %s\n' $f $(xxd -p $f);done
bom-utf16be c3a40a
bom-utf16le c3a40a
   bom-utf8 c3a40a
    utf16be 00e4000a
    utf16le e4000a00
       utf8 c3a40a

3

나는 그 질문이 유닉스 / 리눅스에 관한 것이라는 것을 알고 있으며, 유닉스에 도전하는 사람들에게 좋은 옵션을 언급 할 가치가 있다고 생각했습니다.
WordPress 프로젝트에서 동일한 문제가 발생했으며 (BOM이 rss 피드 및 페이지 유효성 검사에 문제를 일으켰습니다) BOM에있는 파일을 찾기 위해 상당히 큰 디렉토리 트리의 모든 파일을 조사해야했습니다. Replace Pioneer 라는 응용 프로그램을 찾았 습니다.

Batch Runner-> Search (하위 폴더의 모든 파일 찾기)-> Replace Template-> Binary remove BOM (준비된 검색 및 교체 템플릿이 있습니다).

가장 우아한 솔루션은 아니었고 프로그램을 설치해야하는 단점이있었습니다. 하지만 내 주변에서 무슨 일이 일어나고 있는지 알아 내자 매력처럼 작동했습니다 (BOM이 포함 된 약 2300 개 파일 중 3 개 파일을 찾았습니다).


1
솔루션을 찾았을 때 너무 기뻤지 만 회사 컴퓨터에 소프트웨어를 설치할 권한이 없습니다. 대안을 찾을 때까지 오늘 많은 시간이 걸렸습니다 : PythonScript 플러그인과 함께 Notepad ++ 사용. superuser.com/questions/418515/… 어쨌든 감사합니다!
Hoàng Long
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.