Byte order mark
바이트 순서 표식(Byte Order Mark, BOM)은 유니코드에서 엔디안을 구별하기 위해 사용되는 문자로, 문자 값은 U+FEFF이다.
UTF-16, UTF-32와 같은 인코딩에서는 엔디안의 종류에 따라 문자열의 값이 완전히 달라지므로, 문자열의 엔디안을 구별할 수 있는 표식이 필요하다. 이에 따라 유니코드 문자열 앞에 BOM 문자를 붙여, 맨 처음에 읽히는 값에 따라 엔디안을 구별한다.
예를 들어, UTF-16에서 빅 엔디안의 경우에 문자열의 가장 처음 두 바이트는 FE FF가 된다. 리틀 엔디안의 경우에는 FF FE가 된다.
BOM
각 유니코드 인코딩 방법에 따른 BOM 값은 다음과 같다.
Encoding | Representation |
| |
UTF-16 빅 엔디안 | |
UTF-16 리틀 엔디안 | |
UTF-32 빅 엔디안 | |
UTF-32 리틀 엔디안 | |
SCSU | |
UTF-EBCDIC | |
BOCU-1 | |
VIM 에서 BOM 확인 방법
참고로 vim에서 확인하면 다음과 같다:
Byte_order_mark_-vim-_text.png
<feff> 로 출력되어, UTF-16 빅엔디언 BOM 처럼 보이지만
이걸 xxd(vim 명령은 :%!xxd
이다)으로 확인하면 다음과 같이 첫 세 바이트에 BOM 바이트가 보인다:
Byte_order_mark_-vim-_xxd.png
ef bb bf
이므로 UTF-8 BOM 이다.
그래서 VIM 에서는 BOM 출력 오류를 주의해야 한다.
UTF-8 BOM 제거 스크립트
UTF-8 BOM (ef bb bf
)을 제거하는 bash 스크립트는 다음과 같다:
#!/bin/bash
# 디렉토리를 재귀적으로 탐색하면서 파일 목록을 얻는 함수
function find_files() {
local dir=$1
find "$dir" -type f
}
# 파일의 BOM(Byte Order Mark)을 제거하는 함수
function remove_bom() {
local file=$1
if [[ $(head -c3 "$file") == $'\xef\xbb\xbf' ]]; then
tail -c +4 "$file" > "${file}.tmp"
mv "${file}.tmp" "$file"
fi
}
# 디렉토리에서 파일을 찾아서 BOM을 제거하는 함수
function remove_bom_recursive() {
local dir=$1
for file in $(find_files "$dir"); do
remove_bom "$file"
done
}
# 스크립트 실행 시작
if [[ -n "$1" ]]; then
# 첫 번째 인자로 전달된 디렉토리에서 BOM 제거 시작
remove_bom_recursive "$1"
else
# 현재 디렉토리에서 BOM 제거 시작
remove_bom_recursive .
fi