题
如何会 awk
用于删除一个的脚本(大概是一行) 物料清单 看起来像?
规格:
- 打印第一行之后的每一行 (
NR > 1
) - 对于第一行:如果它开始于
#FE #FF
或者#FF #FE
, ,删除那些并打印其余的
解决方案
尝试这个:
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 字节。
其他提示
使用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
参数意味着“就地”,并且将更新文件而不需要重定向或奇怪的技巧。
在苹果机上:
这 awk
另一个答案中的解决方案有效, ,但是 sed
上面的命令不起作用。至少在 Mac (Sierra) 上 sed
文档没有提到支持十六进制转义 ala \xef
.
通过管道到任何程序都可以实现类似的技巧 sponge
工具来自 更多实用程序:
awk '…' INFILE | sponge INFILE
不是 awk,但更简单:
tail -c +4 UTF8 > UTF8.nobom
检查 BOM:
hd -n 3 UTF8
如果 BOM 存在,您将看到: 00000000 ef bb bf ...
除了将 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 的文件。发现一个应用程序叫 更换先锋 并在其中:
Batch Runner -> 搜索(查找子文件夹中的所有文件)-> 替换模板 -> 二进制删除 BOM(有一个现成的搜索和替换模板)。
这不是最优雅的解决方案,并且确实需要安装程序,这是一个缺点。但一旦我发现了我周围发生的事情,它就像一个魅力(并从大约 2300 个文件中找到了 3 个带有 BOM 的文件)。