В целях отладки мне нужно рекурсивно искать в каталоге все файлы, которые начинаются с отметки порядка байтов (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Он не работает с именами файлов, которые содержат разрыв строки, но таких файлов в любом случае ожидать не стоит.
Есть ли более короткое или элегантное решение?
Есть ли какие-нибудь интересные текстовые редакторы или макросы для текстовых редакторов?






Если вы принимаете некоторые ложные срабатывания (в случае, если есть нетекстовые файлы или в маловероятном случае есть 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 без спецификации, если в начале строки у них есть пробелы нулевой ширины.Я бы использовал что-то вроде:
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 с помощью маркера спецификации .. это потому, что он выполняет поиск по всему документу, а не только по первой строке.
Или с ack: "ack '\ xEF \ xBB \ xBF'"
измените команду sed, чтобы добавить 1 перед ведущим 's', чтобы она применялась только к первой строке
grep также находит много двоичных файлов, исправляет это, используя что-то вроде egrep -rl $'^\xEF\xBB\xBF', и даже это начало строк greps, а не только первую строку.
Используйте grep -rlI $'\xEF\xBB\xBF' ., чтобы игнорировать двоичные файлы.
Обнаруживает и изменяет JPG и другие двоичные файлы, как уже было сказано.
Какой смысл создавать файл «.bak» с помощью sed, чтобы удалить его в следующем «-exec»? Я отредактировал его, чтобы sed просто исправлял файлы на месте. См .: stackoverflow.com/posts/2858757/…
Есть ли способ заставить его игнорировать папку .git?
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}'
Как мне изменить ваш код, чтобы исправить эти файлы после того, как они были найдены?
Лучший и самый простой способ сделать это в Windows:
Total Commander → перейдите в корневой каталог проекта → найдите файлы (Alt + F7) → типы файлов *. * → Найдите текст «EF BB BF» → установите флажок «Hex» → поиск
И вы получите список :)
Приятно, особенно использование моего давнего любимого Total commander, но, к сожалению, он страдает той же проблемой, что и многие другие: он ищет все байты в файле, сообщается о большом количестве изображений и т. д. Это можно немного улучшить, используя RegEx вместо Hex и выполняя поиск по запросу «^ \ xEF \ xBB \ xBF», который удалит многие изображения, но все еще содержит файлы с спецификацией на полпути (хотя их должно быть немного) и, конечно, любые двоичные файлы, которые имеют код символа новой строки ascii непосредственно перед спецификацией. Тем не менее, все изображения пропали в моем тестовом поиске.
Для пользователей Windows см. это (хороший PHP-скрипт для поиска BOM в вашем проекте).
На связанном веб-сайте отображается: «Веб-сайт не в сети, кешированная версия недоступна».
тот же скрипт также доступен в github: github.com/emrahgunduz/BomCleaner
Спасибо, дружище, твой ответ спас мне день.
И BOM Finder: github.com/svn2github/wikia/blob/master/extensions/FCKeditor /… (на случай, если кому-то не нравится «автоматическая» очистка, или он просто хочет найти файлы с BOM)
Излишним решением для этого является 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)
Если вы ищете файлы UTF, команда файла работает. Он расскажет вам, какова кодировка файла. Если там есть какие-либо символы, отличные от ASCII, он будет предлагать UTF.
file *.php | grep UTF
Однако это не будет работать рекурсивно. Вы, вероятно, можете настроить какую-нибудь причудливую команду, чтобы сделать ее рекурсивной, но я просто искал каждый уровень индивидуально, как показано ниже, пока у меня не закончились уровни.
file */*.php | grep UTF
Вам все еще нужна "голова 1" в трубе перед grep