Элегантный способ поиска файлов UTF-8 с помощью спецификации? - PullRequest
84 голосов
/ 15 октября 2008

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

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

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

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

Существуют ли какие-либо интересные текстовые редакторы или макросы для текстовых редакторов?

Ответы [ 11 ]

154 голосов
/ 18 мая 2010

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

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

Я люблю "найти":)

Предупреждение Выше изменит двоичные файлы, содержащие эти три символа.

.

Если вы хотите просто показать файлы спецификации, используйте это:

grep -rl $'\xEF\xBB\xBF' .
38 голосов
/ 20 сентября 2011

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

Total Commander & rarr; перейти к корневому каталогу проекта & rarr; найти файлы ( Alt + F7 ) & rarr; типы файлов *. * & rarr; Найти текст "EF BB BF" & rarr; установите флажок «Hex» & rarr; Поиск

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

12 голосов
/ 21 мая 2010
find . -type f -print0 | xargs -0r awk '
    /^\xEF\xBB\xBF/ {print FILENAME}
    {nextfile}'

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

7 голосов
/ 17 октября 2008

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

fgrep -rl `echo -ne '\xef\xbb\xbf'` .
5 голосов
/ 13 июля 2013

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

grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}'
5 голосов
/ 17 октября 2008

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

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

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

4 голосов
/ 03 ноября 2011

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

3 голосов
/ 21 декабря 2011

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

phptags --warn ./

Будет выводить что-то вроде:

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

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

2 голосов
/ 03 апреля 2012

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

find . -iname *.js -type f -exec sed 's/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;
2 голосов
/ 17 октября 2008
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, если они имеют пробелы нулевой ширины в начале строки
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...