Answers:
试试这个:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE
在第一条记录(行)上,删除BOM表字符。打印每条记录。
或更短一点,使用以下知识:awk中的默认操作是打印记录:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE
1
是最短的条件,总是求值为true,因此将打印每条记录。
请享用!
-附录-
Unicode字节顺序标记(BOM)常见问题解答包含下表,列出了每种编码的确切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
因此,您可以从上表中看到\xef\xbb\xbf
与EF BB BF
UTF-8
BOM表字节的对应关系。
awk '{if(NR==1)sub(/^\xef\xbb\xbf/,"");print}' INFILE > OUTFILE
并确保INFILE和OUTFILE不同!
perl -i.orig -pe 's/^\x{FFFE}//' badfile
,则可以依靠PERL_UNICODE和/或PERLIO变量进行编码。PERL_UNICODE = SD适用于UTF-8;对于其他人,则需要PERLIO。
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1'
使用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
文档中没有提到支持十六进制转义ala \xef
。
任何程序都可以通过sponge
从moreutils传递到该工具来实现类似的技巧:
awk '…' INFILE | sponge INFILE
10.11.6
,这不起作用,但是官方答案stackoverflow.com/a/1068700/9636可以正常工作。
不是awk,但是更简单:
tail -c +4 UTF8 > UTF8.nobom
要检查BOM:
hd -n 3 UTF8
如果存在BOM,您将看到: 00000000 ef bb bf ...
cat file1.utf8 file2.utf8 file3.utf3 > allfiles.utf8
会被打破。切勿在UTF-8上使用BOM。期。
hd
不适用于OS X(截至10.8.2),所以检查的UTF-8 BOM那里,你可以使用以下命令:head -c 3 file | od -t x1
。
除了将CRLF行尾转换为LF之外,dos2unix
还删除BOM表:
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
我知道这个问题是针对unix / linux的,我认为值得一提的是unix受到挑战的一个好选择(在Windows上,带有UI)。
我在一个WordPress项目上遇到了同样的问题(BOM导致rss feed和页面验证出现问题),我不得不查看一个很大的目录树中的所有文件,以找到BOM表中的所有文件。在其中找到一个名为“ 替换先锋”的应用程序:
批处理运行器->搜索(在子文件夹中查找所有文件)->替换模板->二进制删除BOM(为此,有一个现成的搜索和替换模板)。
这不是最优雅的解决方案,它确实需要安装程序,这是一个缺点。但是,一旦我发现周围发生的事情,它就像一个咒语一样工作(从大约2300个BOM中找到了3个文件)。