Unicode 使用awk删除字节顺序标记

Unicode 使用awk删除字节顺序标记,unicode,awk,byte-order-mark,Unicode,Awk,Byte Order Mark,一个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' IN

一个
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的最短条件,因此打印每条记录

享受吧

--附录--

下表列出了每个编码的确切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,而是更简单:

tail -c +4 UTF8 > UTF8.nobom
要检查BOM表,请执行以下操作:

hd -n 3 UTF8

如果存在BOM,您将看到:
00000000 ef bb bf…
使用GNU
sed
(在Linux或Cygwin上):

关于FreeBSD:

sed -i .bak '1 s/^\xef\xbb\xbf//' *.txt
使用GNU或FreeBSD的优点
sed
-i
参数表示“就位”,并将更新文件,而无需重定向或奇怪的技巧

在Mac上:

,但上面的
sed
命令不起作用。至少在Mac(Sierra)
sed
文档中没有提到支持十六进制转义ala
\xef

通过管道连接到
海绵
工具,任何程序都可以实现类似的技巧:


我知道这个问题是针对unix/linux的,我认为值得一提的是,对于面临unix挑战的用户(在windows上,使用UI)来说,这是一个不错的选择。
我在WordPress项目中遇到了同样的问题(BOM导致rss提要和页面验证出现问题),我必须查看一个相当大的目录树中的所有文件,以找到与BOM相关的文件。在其中找到一个名为的应用程序:

Batch Runner->Search(查找子文件夹中的所有文件)->Replace Template->Binary remove BOM(有一个现成的搜索和替换模板)


这不是最优雅的解决方案,它确实需要安装一个程序,这是一个缺点。但一旦我发现我周围发生了什么,它就像一个符咒(在大约2300个BOM文件中找到了3个文件)

除了将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

似乎子语句中间的点太多了(至少,我的AWK抱怨过)。除此之外,这正是我搜索的,谢谢!但是,此解决方案仅适用于UTF-8编码的文件。对于其他类型,如UTF-16,请参阅维基百科以获取相应的BOM表示:因此:
awk'{if(NR==1)sub(/^\xef\xbb\xbf/,”);print}'infle>OUTFILE
,并确保infle和OUTFILE是不同的!如果使用
perl-i.orig-pe的/^\x{FFFE}//'badfile
,则可以使用perl_UNICODE和/或PERLIO环境变量进行编码。PERL_UNICODE=SD适用于UTF-8;对于其他人来说,你需要PERLIO。可能稍微短一点的版本:
awk'NR==1{sub(/^\xef\xbb\xbf/,“”)}1'
bom对于UTF-16是2字节,对于UTF-32是4字节,当然一开始就没有必要使用UTF-8。@KarolyHorvath是的,没错。不建议使用它。它会打碎东西。编码应该由更高级别的协议指定。@tchrist:你的意思是它会破坏坏东西吗?:)合适的应用程序应该能够处理这个BOM。@KarolyHorvath我的意思是它会破坏很多程序。我不是这么说的吗?当您以UTF-16或UTF-32编码打开流时,解码器知道不计算BOM。使用UTF-8时,解码器将BOM作为数据呈现。这是无数程序中的语法错误。UTF-8文件上的BOM表放错了位置,令人头痛:它们是一个错误!他们破坏了很多东西。即使只是
cat file1.utf8 file2.utf8 file3.utf3>所有文件.utf8
都将被破坏。切勿在UTF-8上使用BOM。期间。
hd
在OS X上不可用(从10.8.2开始),因此要在那里检查UTF-8 BOM,可以使用以下命令:
head-c3 file | od-tx1
。我在Mac OS X上精确地尝试了第二个命令,结果是“成功”,但是替换实际上并没有发生。值得注意的是,这些命令替换了一个特定的字节序列,即。可能您的文件有不同的BOM表序列。(除此之外,我无能为力,因为我没有Mac)当我在OS X上对一个使用0xef 0xbb 0xbf作为BOM的文件尝试第二个命令时,它实际上没有进行替换。在OSX中,我只能通过perl实现这一点,如下所示:在OS X El Capitan
10.11.6
,这不起作用,但是官方的回答很好。我很高兴找到你的解决方案,但是我没有在公司电脑上安装软件的特权。今天花了很多时间,直到我找到了替代方法:使用记事本++和PythonScript插件。无论如何谢谢你!
dos2unix *.txt
$ 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