Елегантний спосіб пошуку файлів UTF-8 за допомогою BOM?


94

Для налагодження мені потрібно рекурсивно шукати в каталозі всі файли, які починаються з позначки порядку байтів 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

Він не працює з назви файлів, які містять розрив рядка, але таких файлів у будь-якому разі не варто очікувати.

Чи є якесь коротше або елегантніше рішення?

Чи є якісь текстові редактори чи макроси для текстових редакторів?

Відповіді:


166

А що з цією простою командою, яка не просто знаходить, але очищає противну BOM? :)

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

Я люблю "знаходити" :)

Попередження Вищезгадане змінює бінарні файли, які містять ці три символи.

Якщо ви хочете просто показати файли специфікації, використовуйте цей:

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

9
Неправильно виявляє PDF за допомогою маркера специфікації .. це тому, що він здійснює пошук у цілому документі, а не лише в першому рядку
Олів’є Рефало

1
Або з ack: "ack '\ xEF \ xBB \ xBF'"
Смар

5
змініть команду sed, щоб додати 1 перед ведучими 's', так це стосується лише першого рядка
Ben Combee

27
Використовуйте grep -rlI $'\xEF\xBB\xBF' .для ігнорування двійкових файлів.
dbernard

1
Виявляє та модифікує JPG та інші двійкові файли, як уже було сказано.
Jehy

41

Найкращий і найпростіший спосіб зробити це в Windows:

Total Commander → перейти до кореневого редактора проекту → знайти файли ( Alt+ F7) → типи файлів *. * → Знайти текст «EF BB BF» → встановити прапорець «Hex» → пошук

І ви отримуєте список :)


4
Приємно, особливо використання мого давно улюбленого командира Total, але, на жаль, це страждає тим же самим питанням, що і багато інших: він здійснює пошук усіх байтів у флі, так багато зображень тощо повідомляється. Це можна дещо покращити, скориставшись RegEx замість Hex та пошуком "^ \ xEF \ xBB \ xBF", який видалить багато зображень, але все ще має файли, які мають BOM на півдорозі файлу (хоча їх має бути небагато), і звичайно будь-які двійкові файли, у яких випадково є код нового рядка ascii, просто перед специфікацією. Тим не менше, у моєму тестовому пошуку всі зображення зникли.
Леголас

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

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


1
Потрібно працювати з наступним на Linux (RHEL6) -find . -type f -print0 | xargs -0 awk '/^\xEF\xBB\xBF/ {print FILENAME} {nextfile}'
Олів'є Рефало

Як мені змінити ваш код, щоб виправити ці файли після їх знаходження?
Чорний

7

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

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

5

Я б використав щось на зразок:

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

Що гарантуватиме, що специфікація відбувається з першого байта файлу.


5

Ви можете використовувати, grepщоб знайти їх і Perl, щоб видалити їх так:

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

Цей працював на мене, прийнята відповідь не стала (я на Mac)
mjsarfatti

4

Для користувача Windows дивіться це (хороший скрипт PHP для пошуку BOMу вашому проекті).


На пов'язаному веб-сайті видно: "Веб-сайт офлайн, не доступна кешована версія".
вог

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

Дякую приятелю, Ваша відповідь врятувала мені день.
Krunal Panchal,

І BOM Finder: github.com/svn2github/wikia/blob/master/extensions/FCKeditor/… (якщо комусь не подобається "автоматичне" прибирання, або просто хоче знайти файли з BOM)
meloniq

3

Рішенням надмірного рівня для цього є phptags(не viінструмент з однойменною назвою), який спеціально шукає PHP-скрипти:

phptags --warn ./

Виведе щось на зразок:

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

І --whitespaceрежим автоматично виправить такі проблеми (рекурсивно, але стверджує, що він переписує лише .php-скрипти.)


2
find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /'
  • find -print0 ставить null \ 0 між кожним іменем файлу замість використання нових рядків
  • xargs -0 очікує, що нульові аргументи замість розділених рядків
  • grep -l перераховує файли, які відповідають регексу
  • ^\xeff\xbb\xbfЗвичайний вираз не зовсім правильний, оскільки він буде відповідати файлам UTF-8 без BOMed, якщо вони мають пробіли нульової ширини на початку рядка

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

2

Я використав це для виправлення лише файлів JavaScript:

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

0

Якщо ви шукаєте файли UTF, команда file працює. Це покаже вам, що таке кодування файлу. Якщо в ньому є якісь символи, що не належать до ASCII, він створить UTF.

file *.php | grep UTF

Це не буде працювати рекурсивно, хоча. Можливо, ви можете підробити якусь химерну команду, щоб зробити її рекурсивною, але я просто шукав кожен рівень окремо, як показано нижче, поки не закінчився рівень.

file */*.php | grep UTF
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.