Câu trả lời:
Thử cái này:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE
Trên bản ghi đầu tiên (dòng), hãy xóa các ký tự BOM. In mọi bản ghi.
Hoặc ngắn hơn một chút, sử dụng kiến thức rằng hành động mặc định trong awk là in bản ghi:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE
1
là điều kiện ngắn nhất luôn đánh giá là true, vì vậy mỗi bản ghi được in ra.
Thưởng thức!
- BỔ SUNG -
Câu hỏi thường gặp về Dấu đơn hàng Unicode Byte (BOM) bao gồm bảng sau liệt kê các byte BOM chính xác cho mỗi bảng mã:
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
Do đó, bạn có thể thấy cách \xef\xbb\xbf
tương ứng với các EF BB BF
UTF-8
byte BOM từ bảng trên.
awk '{if(NR==1)sub(/^\xef\xbb\xbf/,"");print}' INFILE > OUTFILE
, hãy đảm bảo rằng INFILE và OUTFILE khác nhau!
perl -i.orig -pe 's/^\x{FFFE}//' badfile
bạn có thể dựa vào các biến PERL_UNICODE và / hoặc PERLIO để mã hóa. PERL_UNICODE = SD sẽ hoạt động cho UTF-8; đối với những người khác, bạn cần PERLIO.
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1'
Sử dụng GNU sed
(trên Linux hoặc Cygwin):
# Removing BOM from all text files in current directory:
sed -i '1 s/^\xef\xbb\xbf//' *.txt
Trên FreeBSD:
sed -i .bak '1 s/^\xef\xbb\xbf//' *.txt
Lợi thế của việc sử dụng GNU hoặc FreeBSD sed
: -i
tham số có nghĩa là "tại chỗ" và sẽ cập nhật tệp mà không cần chuyển hướng hoặc các thủ thuật kỳ lạ.
Trên Mac:
awk
Giải pháp này trong một câu trả lời khác hoạt động , nhưng sed
lệnh trên không hoạt động. Ít nhất trên Mac (Sierra) sed
tài liệu không đề cập đến việc hỗ trợ thoát thập lục phân ala \xef
.
Một thủ thuật tương tự có thể đạt được với bất kỳ chương trình nào bằng cách chuyển đến sponge
công cụ từ moreutils :
awk '…' INFILE | sponge INFILE
10.11.6
, điều này không hoạt động, nhưng câu trả lời chính thức stackoverflow.com/a/1068700/9636 hoạt động tốt.
Không phải awk, nhưng đơn giản hơn:
tail -c +4 UTF8 > UTF8.nobom
Để kiểm tra BOM:
hd -n 3 UTF8
Nếu BOM có mặt, bạn sẽ thấy: 00000000 ef bb bf ...
cat file1.utf8 file2.utf8 file3.utf3 > allfiles.utf8
sẽ bị phá vỡ. Không bao giờ sử dụng BOM trên UTF-8. Giai đoạn = Stage.
hd
không có sẵn trên OS X (tính 10.8.2), do đó để kiểm tra một UTF-8 BOM đó bạn có thể sử dụng như sau: head -c 3 file | od -t x1
.
Ngoài việc chuyển đổi phần cuối dòng CRLF thành LF, dos2unix
cũng loại bỏ các BOM:
dos2unix *.txt
dos2unix
cũng chuyển đổi tệp UTF-16 có BOM (nhưng không phải tệp UTF-16 không có BOM) thành UTF-8 không có BOM:
$ 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
Tôi biết câu hỏi hướng đến unix / linux, tôi nghĩ sẽ đáng để đề cập đến một lựa chọn tốt cho unix bị thách thức (trên windows, với giao diện người dùng).
Tôi gặp phải vấn đề tương tự trên một dự án WordPress (BOM đã gây ra sự cố với nguồn cấp dữ liệu rss và xác thực trang) và tôi phải xem xét tất cả các tệp trong một cây thư mục khá lớn để tìm tệp có trong BOM. Tìm thấy một ứng dụng tên là Replace Pioneer và trong đó:
Batch Runner -> Search (để tìm tất cả các tệp trong các thư mục con) -> Replace Template -> Binary remove BOM (có một mẫu tìm kiếm và thay thế được tạo sẵn cho việc này).
Nó không phải là giải pháp thanh lịch nhất và nó yêu cầu cài đặt một chương trình, đó là một nhược điểm. Nhưng một khi tôi phát hiện ra những gì đang diễn ra xung quanh mình, nó hoạt động như một cái duyên (và tìm thấy 3 tệp trong số khoảng 2300 tệp có BOM).