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

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

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
94
0
69 772
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

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

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

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 не совсем корректно, так как оно будет соответствовать файлам UTF-8 без спецификации, если в начале строки у них есть пробелы нулевой ширины.

Вам все еще нужна "голова 1" в трубе перед grep

MSalters 17.10.2008 18:08

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

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

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

Ответ принят как подходящий

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

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

Люблю "находить" :)

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

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

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

Неправильно определяет PDF с помощью маркера спецификации .. это потому, что он выполняет поиск по всему документу, а не только по первой строке.

Olivier Refalo 23.09.2011 18:38

Или с ack: "ack '\ xEF \ xBB \ xBF'"

Smar 17.03.2012 05:46

измените команду sed, чтобы добавить 1 перед ведущим 's', чтобы она применялась только к первой строке

Ben Combee 06.06.2012 08:07

grep также находит много двоичных файлов, исправляет это, используя что-то вроде egrep -rl $'^\xEF\xBB\xBF', и даже это начало строк greps, а не только первую строку.

Evgeny 12.09.2012 15:45

Используйте grep -rlI $'\xEF\xBB\xBF' ., чтобы игнорировать двоичные файлы.

dbernard 06.11.2012 00:07

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

Jehy 28.01.2014 14:38

Какой смысл создавать файл «.bak» с помощью sed, чтобы удалить его в следующем «-exec»? Я отредактировал его, чтобы sed просто исправлял файлы на месте. См .: stackoverflow.com/posts/2858757/…

vog 17.06.2017 09:22

Есть ли способ заставить его игнорировать папку .git?

Aaron Franke 13.12.2019 10:22

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

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

Got работает со следующим в Linux (RHEL6) - find . -type f -print0 | xargs -0 awk '/^\xEF\xBB\xBF/ {print FILENAME} {nextfile}'

Olivier Refalo 23.09.2011 18:37

Как мне изменить ваш код, чтобы исправить эти файлы после того, как они были найдены?

Black 05.08.2019 12:55

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

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

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

Приятно, особенно использование моего давнего любимого Total commander, но, к сожалению, он страдает той же проблемой, что и многие другие: он ищет все байты в файле, сообщается о большом количестве изображений и т. д. Это можно немного улучшить, используя RegEx вместо Hex и выполняя поиск по запросу «^ \ xEF \ xBB \ xBF», который удалит многие изображения, но все еще содержит файлы с спецификацией на полпути (хотя их должно быть немного) и, конечно, любые двоичные файлы, которые имеют код символа новой строки ascii непосредственно перед спецификацией. Тем не менее, все изображения пропали в моем тестовом поиске.

Legolas 08.09.2015 16:26

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

На связанном веб-сайте отображается: «Веб-сайт не в сети, кешированная версия недоступна».

vog 09.01.2012 16:57

тот же скрипт также доступен в github: github.com/emrahgunduz/BomCleaner

emrahgunduz 16.04.2013 19:26

Спасибо, дружище, твой ответ спас мне день.

Krunal Panchal 21.09.2015 11:09

И BOM Finder: github.com/svn2github/wikia/blob/master/extensions/FCKeditor‌ /… (на случай, если кому-то не нравится «автоматическая» очистка, или он просто хочет найти файлы с BOM)

meloniq 18.05.2016 19:43

Излишним решением для этого является 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 \;

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

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

Этот сработал для меня, принятый ответ - нет (я на Mac)

mjsarfatti 31.03.2016 18:18

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

file *.php | grep UTF

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

file */*.php | grep UTF

Другие вопросы по теме