出于调试目的,我需要递归地在目录中搜索所有以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
它不适用于包含换行符的文件名,但是这样的文件无论如何都不是预期的。
有没有更短或更优雅的解决方案?
有什么有趣的文本编辑器或文本编辑器的宏吗?
这个简单的命令怎么办?它不仅能找到而且能清除讨厌的BOM?:)
find . -type f -exec sed '1s/^'xEF'xBB'xBF//' -i {} ';
我喜欢"寻找":)
警告以上内容将修改包含这三个字符的二进制文件。
如果您只想显示BOM文件,请使用以下文件:
grep -rl $''xEF'xBB'xBF' .
在Windows上做到这一点的最佳和最简单的方法:
总司令&rar;转到项目的根目录&rar;查找文件(Alt+F7)→文件类型*.*→查找文本"EF BB BF"&rar;选中"十六进制"复选框→搜索
您得到的列表是:)
find . -type f -print0 | xargs -0r awk '
/^'xEF'xBB'xBF/ {print FILENAME}
{nextfile}'
上面给出的大多数解决方案测试的内容都超过了文件的第一行,即使有些解决方案(如Marcus的解决方案)会过滤结果。这个解决方案只测试每个文件的第一行,所以应该会更快一些。
如果您接受一些假阳性(如果有非文本文件,或者在不太可能的情况下,文件中间有一个ZWNBSP),您可以使用grep:
fgrep -rl `echo -ne ''xef'xbb'xbf'` .
您可以使用grep
来查找它们,并使用Perl来剥离它们,如下所示:
grep -rl $''xEF'xBB'xBF' . | xargs perl -i -pe 's{'xEF'xBB'xBF}{}'
我会使用这样的东西:
grep -orHbm1 "^`echo -ne ''xef'xbb'xbf'`" . | sed '/:0:/!d;s/:0:.*//'
这将确保BOM表从文件的第一个字节开始出现。
对于Windows用户,请参阅此(用于在项目中查找BOM
的好PHP脚本)。
phptags
(不是同名的vi
工具)是一个过度使用的解决方案,它专门查找PHP脚本:
phptags --warn ./
将输出类似以下内容:
./invalid.php: TRAILING whitespace ("?>'n")
./invalid.php: UTF-8 BOM alone ("'xEF'xBB'xBF")
--whitespace
模式将自动修复这些问题(递归地,但断言它只重写.php脚本。)
我只使用它来更正JavaScript文件:
find . -iname *.js -type f -exec sed 's/^'xEF'xBB'xBF//' -i.bak {} '; -exec rm {}.bak ';
find -type f -print0 | xargs -0 grep -l `printf '^'xef'xbb'xbf'` | sed 's/^/found BOM in: /'
find -print0
在每个文件名之间加一个null ''0,而不是使用新行xargs -0
需要以null分隔的参数,而不是以行分隔的参数grep -l
列出了与正则表达式匹配的文件- regex
^'xeff'xbb'xbf
并不完全正确,因为如果非BOMed UTF-8文件在一行的开头有零宽度空格,它将匹配这些文件
如果您正在查找UTF文件,file命令会起作用。它会告诉你文件的编码是什么。如果其中有任何非ASCII字符,它会显示UTF。
file *.php | grep UTF
不过,这不会递归地工作。您可能可以设置一些奇特的命令使其递归,但我只是像下面这样单独搜索每个级别,直到用完级别为止。
file */*.php | grep UTF