用BOM搜索UTF-8文件的简便方法?


94

为了进行调试,我需要在目录中递归搜索所有以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

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

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

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

Answers:


166

这个简单的命令不仅找到而且清除了讨厌的BOM,该怎么办?:)

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

我爱“发现” :)

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

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

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

9
错误地使用BOM标记检测PDF ..这是因为它搜索整个文档,而不仅仅是第一行
Olivier Refalo

1
或ACK: “确认'\ XEF \ XBB \ XBF'”
Smar的

5
更改sed命令以在前导“ s”之前添加1,因此它仅适用于第一行
Ben Combee,2012年

27
使用grep -rlI $'\xEF\xBB\xBF' .忽略二进制文件。
dbernard 2012年

1
如前所述,检测并修改JPG和其他二进制文件。
Jehy 2014年

41

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

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

你会得到列表:)


4
很好,尤其是使用了我长期以来最喜欢的Total指挥官,但是不幸的是,这和许多其他命令一样遇到了同样的问题:它在文件中搜索所有字节,因此报告了很多图像等。通过使用RegEx而不是Hex并搜索“ ^ \ xEF \ xBB \ xBF”,可以略微改善此效果,这将消除许多图像,但仍然具有BOM处于文件中间的文件(尽管应该很少),当然在BOM表之前恰好具有ascii换行符的任何二进制文件。不过,所有图片在我的测试搜索中都消失了。
莱戈拉斯2015年

13
find . -type f -print0 | xargs -0r awk '
    /^\xEF\xBB\xBF/ {print FILENAME}
    {nextfile}'

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


1
在Linux(RHEL6)上使用了以下工具find . -type f -print0 | xargs -0 awk '/^\xEF\xBB\xBF/ {print FILENAME} {nextfile}'
Olivier Refalo

找到这些文件后,我该如何修改您的代码以修复这些文件?
黑色

7

如果您接受一些误报(如果有非文本文件,或者在不太可能的情况下文件中间有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上)
mjsarfatti

4

对于Windows用户,请参阅此文件BOM在项目中找到的良好PHP脚本)。


链接的网站显示:“网站离线,没有可用的缓存版本”。
vog 2012年

github中也提供了相同的脚本:github.com/emrahgunduz/BomCleaner
emrahgunduz

谢谢朋友,您的回答挽救了我的一天。
Krunal Panchal 2015年

以及BOM查找器:github.com/svn2github/wikia/blob/master/extensions/FCKeditor / ... (以防有人不喜欢“自动”清理,或者只是想用BOM查找文件)
meloniq

3

一个过分的解决方案是phptags(不是vi具有相同名称的工具),它专门用于查找PHP脚本:

phptags --warn ./

将输出类似:

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

并且该--whitespace模式将自动解决此类问题(递归地,但是断言它仅重写.php脚本。)


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并不完全正确,因为如果非BOM格式的UTF-8文件在行首的宽度为零,它将与之匹配

在grep之前,您仍然需要管道中的“ head 1”
MSalters'Oct

2

我用它来更正JavaScript文件:

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

0

如果要查找UTF文件,则使用file命令。它会告诉您文件的编码是什么。如果其中有任何非ASCII字符,它将带有UTF。

file *.php | grep UTF

但这不会递归地起作用。您可能可以装配一些花哨的命令以使其递归,但是我只是像下面这样逐个搜索每个级别,直到用尽所有级别。

file */*.php | grep UTF
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.