代码之家  ›  专栏  ›  技术社区  ›  Boldewyn

使用awk删除字节顺序标记

  •  101
  • Boldewyn  · 技术社区  · 15 年前

    怎么会 awk 用于删除 BOM 看起来像?

    规范:

    • 打印第一行之后的每一行( NR > 1 )
    • 第一行:如果以 #FE #FF #FF #FE ,删除这些并打印其余部分
    5 回复  |  直到 6 年前
        1
  •  110
  •   Heath Borders    8 年前

    试试这个:

    awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE
    

    在第一条记录(行)上,删除物料清单字符。打印每个记录。

    或者稍短一点,使用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字节。

        2
  •  122
  •   Peter Lamberg qed    7 年前

    使用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的优势 塞德 : -i 参数的意思是“就地”,它将更新文件而不需要重定向或奇怪的技巧。

    在Mac上:

    This awk solution in another answer works 但是 塞德 上面的命令不起作用。至少在Mac(Sierra)上 塞德 文档没有提到支持十六进制转义ALA \xef .

    任何程序都可以通过管道连接到 sponge 工具从 moreutils :

    awk '…' INFILE | sponge INFILE
    
        3
  •  41
  •   Steve Clay    14 年前

    不是awk,但更简单:

    tail -c +4 UTF8 > UTF8.nobom
    

    检查物料清单:

    hd -n 3 UTF8
    

    如果存在物料清单,您将看到: 00000000 ef bb bf ...

        4
  •  20
  •   Lri    11 年前

    除了将CRLF行尾转换为LF之外, dos2unix 同时移除物料清单:

    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
    
        5
  •  2
  •   Arnon Zamir    12 年前

    我知道这个问题是针对unix/linux的,我认为有必要为面临挑战的unix(在Windows上,有一个用户界面)提一个好的选择。
    我在一个WordPress项目中遇到了同样的问题(bom导致了RSS提要和页面验证的问题),我必须查看一个相当大的目录树中的所有文件,才能找到bom中的文件。找到一个名为 Replace Pioneer 在其中:

    批处理运行程序->搜索(查找子文件夹中的所有文件)->替换模板->二进制删除物料清单(有现成的搜索和替换模板)。

    这不是最优雅的解决方案,它确实需要安装一个程序,这是一个缺点。但一旦我发现周围发生了什么,它就像一个魅力(并发现了大约2300个与bom有关的文件中的3个)。