出于调试目的,我需要在目录中递归搜索所有以 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 上执行此操作的最佳和最简单的方法:
Total Commander → 转到项目的根目录 → 查找文件 (Alt + F7) → 文件类型 *.* → 查找文本“EF BB BF” → 检查“十六进制”复选框 → 搜索
你得到了清单:)
find . -type f -print0 | xargs -0r awk '
/^\xEF\xBB\xBF/ {print FILENAME}
{nextfile}'
上面给出的大多数解决方案都比文件的第一行测试更多,即使有一些(例如 Marcus 的解决方案)然后过滤结果。此解决方案仅测试每个文件的第一行,因此应该更快一些。
find . -type f -print0 | xargs -0 awk '/^\xEF\xBB\xBF/ {print FILENAME} {nextfile}'
如果您接受一些误报(如果有非文本文件,或者在不太可能的情况下文件中间有 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 用户,请参阅 this(用于在项目中查找 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 在每个文件名之间放置一个空 \0 而不是使用新行
xargs -0 需要空分隔参数而不是行分隔
grep -l 列出与正则表达式匹配的文件
正则表达式 ^\xeff\xbb\xbf 并不完全正确,因为如果非 BOMed UTF-8 文件在行首的宽度为零,它将匹配它们
如果您要查找 UTF 文件,则 file command 有效。它会告诉你文件的编码是什么。如果那里有任何非 ASCII 字符,它会出现 UTF。
file *.php | grep UTF
但这不会递归地工作。您可能可以安装一些花哨的命令来使其递归,但我只是像下面这样单独搜索每个级别,直到我用完级别。
file */*.php | grep UTF
不定期副业成功案例分享
grep -rlI $'\xEF\xBB\xBF' .
忽略二进制文件。