Элегантный способ поиска файлов UTF-8 с помощью спецификации?

Для целей отладки мне нужно рекурсивно искать каталог для всех файлов, начинающихся с знака порядка байтов UTF-8 (BOM). Мое текущее решение - это простая оболочка script:

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

Он не работает с именами файлов, которые содержат разрыв строки, но таких файлов не следует ожидать в любом случае.

Есть ли более короткое или более элегантное решение?

Есть ли интересные текстовые редакторы или макросы для текстовых редакторов?

Ответ 1

Как насчет этой простой команды, которая не просто находит, но очищает неприятную спецификацию?:)

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

Мне нравится "найти":)

Если вы хотите просто показать BOM файлы, используйте следующую команду:

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

Ответ 2

Самый лучший и простой способ сделать это в Windows:

Total Commander → перейдите в проект root dir → найти файлы (Alt + F7) → типы файлов *. * → Найти текст "EF BB BF" → установите флажок "Hex" и rarr; поиск

И вы получите список:)

Ответ 3

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

Большинство приведенных выше решений проверяют больше, чем первая строка файла, даже если некоторые (например, решение Marcus) фильтруют результаты. Это решение проверяет только первую строку каждого файла, поэтому оно должно быть немного быстрее.

Ответ 4

Если вы принимаете ложные срабатывания (в случае отсутствия текстовых файлов или в маловероятном случае есть ZWNBSP в середине файла), вы можете использовать grep:

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

Ответ 5

Я бы использовал что-то вроде:

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

Что обеспечит выполнение спецификации, начиная с первого байта файла.

Ответ 6

Вы можете использовать grep, чтобы найти их и Perl, чтобы вырезать их так:

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

Ответ 7

Для пользователя Windows см. this (хороший PHP script для поиска BOM в вашем проекте).

Ответ 8

Решение overkill для этого phptags (а не инструмент vi с тем же именем), который специально ищет PHP-скрипты

phptags --warn ./

Выведет что-то вроде:

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

И режим --whitespace будет автоматически исправлять такие проблемы (рекурсивно, но утверждает, что он только перезаписывает скрипты .php.)

Ответ 9

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, если они имеют нулевые ширины в начале строки

Ответ 10

Я использовал это, чтобы исправить только файлы JavaScript:

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

Ответ 11

Если вы ищете файлы UTF, то работает команда файла. Он расскажет вам, что такое кодировка файла. Если есть какие-либо несимвольные символы ASCII, они появятся с UTF.

file *.php | grep UTF

Это не будет работать рекурсивно. Вероятно, вы можете придумать какую-нибудь причудливую команду, чтобы сделать ее рекурсивной, но я просто обыскал каждый уровень индивидуально, как показано ниже, до тех пор, пока не закончится уровень.

file */*.php | grep UTF