【发布时间】:2010-11-07 07:22:03
【问题描述】:
用于删除 BOM 的 awk 脚本(可能是单行)会是什么样子?
规格:
- 打印第一行之后的每一行 (
NR > 1) - 对于第一行:如果它以
#FE #FF或#FF #FE开头,请删除这些并打印其余部分
【问题讨论】:
标签: unicode awk byte-order-mark
用于删除 BOM 的 awk 脚本(可能是单行)会是什么样子?
规格:
NR > 1)#FE #FF 或 #FF #FE 开头,请删除这些并打印其余部分【问题讨论】:
标签: unicode awk byte-order-mark
使用 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 上:
This awk solution in another answer works,但上面的sed 命令不起作用。至少在 Mac (Sierra) sed 文档上没有提到支持十六进制转义ala \xef。
通过从moreutils 管道到sponge 工具,任何程序都可以实现类似的技巧:
awk '…' INFILE | sponge INFILE
【讨论】:
10.11.6 上,这不起作用,但官方回答 stackoverflow.com/a/1068700/9636 工作正常。
试试这个:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE
在第一条记录(行)上,删除 BOM 字符。打印每条记录。
或者稍微短一些,使用 awk 中的默认操作是打印记录的知识:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE
1 是始终评估为真的最短条件,因此会打印每条记录。
享受吧!
-- 附录--
Unicode Byte Order Mark (BOM) 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
因此,您可以从上表中看到\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'
不是 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 提要和页面验证出现问题),我不得不查看一个相当大的目录树中的所有文件,才能找到与 BOM 相关的文件。找到了一个名为 Replace Pioneer 的应用程序并在其中:
Batch Runner -> 搜索(查找子文件夹中的所有文件)-> 替换模板 -> 二进制删除 BOM(为此有现成的搜索和替换模板)。
这不是最优雅的解决方案,它确实需要安装程序,这是一个缺点。但是一旦我发现我周围发生了什么,它就像一个魅力(并在大约 2300 个带有 BOM 的文件中找到了 3 个)。
【讨论】: