【问题标题】:Elegant way to search for UTF-8 files with BOM?用 BOM 搜索 UTF-8 文件的优雅方式?
【发布时间】:2010-09-17 07:31:49
【问题描述】:

出于调试目的,我需要在目录中递归搜索所有以 UTF-8 字节顺序标记 (BOM) 开头的文件。我目前的解决方案是一个简单的 shell 脚本:

find -type f |
while read file
do
    if [ "`head -c 3 -- "$file"`" == $'\xef\xbb\xbf' ]
    then
        echo "found BOM in: $file"
    fi
done

或者,如果您更喜欢简短、不可读的单行:

find -type f|while read file;do [ "`head -c3 -- "$file"`" == $'\xef\xbb\xbf' ] && echo "found BOM in: $file";done

它不适用于包含换行符的文件名, 但无论如何也不会出现这样的文件。

有没有更短或更优雅的解决方案?

是否有任何有趣的文本编辑器或文本编辑器的宏?

【问题讨论】:

    标签: php utf-8 shell text-editor


    【解决方案1】:

    这个不仅可以查找而且可以清除讨厌的 BOM 的简单命令怎么样? :)

    find . -type f -exec sed '1s/^\xEF\xBB\xBF//' -i {} \;
    

    我喜欢“寻找”:)

    警告以上将修改包含这三个字符的二进制文件。

    如果您只想显示 BOM 文件,请使用此文件:

    grep -rl $'\xEF\xBB\xBF' .
    

    【讨论】:

    • 错误地检测到带有 BOM 标记的 PDF。这是因为它搜索整个文档,而不仅仅是第一行
    • 或者用 ack: "ack '\xEF\xBB\xBF'"
    • 更改 sed 命令以在前导 's' 前添加 1,使其仅适用于第一行
    • 使用grep -rlI $'\xEF\xBB\xBF' . 忽略二进制文件。
    • 检测和修改 JPG 和其他二进制文件,如前所述。
    【解决方案2】:

    在 Windows 上执行此操作的最佳和最简单的方法:

    Total Commander → 转到项目的根目录 → 查找文件 (Alt + F7) → 文件类型 *.* → 查找文本“EF BB BF” → 检查“十六进制”复选框 → 搜索

    然后你会得到列表:)

    【讨论】:

    • 很好,尤其是我长期以来最喜欢的 Total 指挥官的使用,但不幸的是,它遇到了与许多其他问题相同的问题:它搜索文件中的所有字节,报告了很多图像等。这可以通过使用 RegEx 而不是 Hex 并搜索“^\xEF\xBB\xBF”来稍微改进,这将消除许多图像,但仍然有文件在文件中间有 BOM(尽管应该很少),当然任何恰好在 BOM 之前具有 ascii 换行符的二进制文件。尽管如此,所有图片在我的测试搜索中都消失了。
    【解决方案3】:
    find . -type f -print0 | xargs -0r awk '
        /^\xEF\xBB\xBF/ {print FILENAME}
        {nextfile}'
    

    上面给出的大多数解决方案都比文件的第一行测试更多,即使有一些(例如 Marcus 的解决方案)然后过滤结果。这个解决方案只测试每个文件的第一行,所以应该会快一点。

    【讨论】:

    • Got 在 Linux (RHEL6) 上使用以下内容 - find . -type f -print0 | xargs -0 awk '/^\xEF\xBB\xBF/ {print FILENAME} {nextfile}'
    • 在找到这些文件后,我如何修改您的代码来修复这些文件?
    【解决方案4】:

    如果您接受一些误报(如果有非文本文件,或者在不太可能的情况下文件中间有 ZWNBSP),您可以使用 grep:

    fgrep -rl `echo -ne '\xef\xbb\xbf'` .
    

    【讨论】:

      【解决方案5】:

      您可以使用grep 来查找它们,然后使用 Perl 将它们删除,如下所示:

      grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}'
      

      【讨论】:

      • 这个对我有用,接受的答案没有(我在 Mac 上)
      【解决方案6】:

      我会使用类似的东西:

      grep -orHbm1 "^`echo -ne '\xef\xbb\xbf'`" . | sed '/:0:/!d;s/:0:.*//'
      

      这将确保 BOM 从文件的第一个字节开始出现。

      【讨论】:

        【解决方案7】:

        对于 Windows 用户,请参阅 this(用于在您的项目中查找 BOM 的优秀 PHP 脚本)。

        【讨论】:

        【解决方案8】:

        对此的过度解决方案是 phptags(不是同名的 vi 工具),它专门寻找 PHP 脚本:

        phptags --warn ./
        

        会输出如下内容:

        ./invalid.php: TRAILING whitespace ("?>\n")
        ./invalid.php: UTF-8 BOM alone ("\xEF\xBB\xBF")
        

        --whitespace 模式将自动修复此类问题(递归,但断言它只重写 .php 脚本。)

        【讨论】:

          【解决方案9】:

          我只用它来更正 JavaScript 文件:

          find . -iname *.js -type f -exec sed 's/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;
          

          【讨论】:

            【解决方案10】:
            find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /'
            
            • find -print0 在每个文件名之间放置一个空 \0 而不是使用新行
            • xargs -0 需要空分隔参数而不是行分隔
            • grep -l 列出匹配正则表达式的文件
            • 正则表达式 ^\xeff\xbb\xbf 并不完全正确,因为如果非 BOMed UTF-8 文件在行首的宽度为零,它将匹配它们

            【讨论】:

            • 在 grep 之前的管道中仍然需要一个“head 1”
            【解决方案11】:

            如果您正在寻找 UTF 文件,file command 有效。它会告诉你文件的编码是什么。如果里面有任何非 ASCII 字符,它会出现 UTF。

            file *.php | grep UTF
            

            但这不会递归地工作。您可能可以安装一些花哨的命令来使其递归,但我只是像下面这样单独搜索每个级别,直到我用完级别。

            file */*.php | grep UTF
            

            【讨论】:

              猜你喜欢
              • 2014-03-04
              • 2011-03-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-10-28
              相关资源
              最近更新 更多