100

出于调试目的,我需要递归搜索以 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

它不适用于包含换行符的文件名,但无论如何都不会期望此类文件。

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

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

4

11 回答 11

178

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

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

我喜欢“寻找” :)

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

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

grep -rl $'\xEF\xBB\xBF' .
于 2010-05-18T15:37:42.487 回答
42

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

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

你得到了清单:)

于 2011-09-19T23:06:44.257 回答
13
find . -type f -print0 | xargs -0r awk '
    /^\xEF\xBB\xBF/ {print FILENAME}
    {nextfile}'

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

于 2010-05-21T19:22:13.180 回答
8

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

fgrep -rl `echo -ne '\xef\xbb\xbf'` .
于 2008-10-17T11:55:14.777 回答
6

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

grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}'
于 2013-07-12T21:16:51.320 回答
5

我会使用类似的东西:

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

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

于 2008-10-17T14:12:25.950 回答
4

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

于 2011-11-03T09:34:05.607 回答
3

一个矫枉过正的解决方案是phptags(不是vi同名的工具),它专门寻找 PHP 脚本:

phptags --warn ./

将输出如下内容:

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

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

于 2011-12-21T01:55:46.480 回答
3

我用它来只更正 JavaScript 文件:

find . -iname *.js -type f -exec sed 's/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;
于 2012-04-03T09:05:19.713 回答
2
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 文件在行首的宽度为零,它将匹配它们
于 2008-10-17T13:51:58.333 回答
0

If you are looking for UTF files, the file command works. It will tell you what the encoding of the file is. If there are any non ASCII characters in there it will come up with UTF.

file *.php | grep UTF

That won't work recursively though. You can probably rig up some fancy command to make it recursive, but I just searched each level individually like the following, until I ran out of levels.

file */*.php | grep UTF
于 2014-10-16T14:28:10.630 回答