Использование awk для удаления метки порядка байтов
Как бы awk
скрипт (предположительно однострочный) для удаления спецификации выглядит?
Спецификация:
- печатать каждую строку после первой (
NR > 1
) - для первой строки: если это начинается с
#FE #FF
или же#FF #FE
удалите их и распечатайте остальные
5 ответов
Попробуй это:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE
В первой записи (строке) удалите символы спецификации. Распечатайте каждую запись.
Или немного короче, используя знание, что действие по умолчанию в awk - это распечатать запись:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE
1
является кратчайшим условием, которое всегда оценивается как истинное, поэтому каждая запись печатается.
Наслаждайтесь!
- ДОБАВЛЕНИЕ -
Часто задаваемые вопросы по метке порядка байтов в кодировке Unicode включают следующую таблицу, в которой перечислены точные байты спецификации для каждой кодировки:
Bytes | Encoding Form
--------------------------------------
00 00 FE FF | UTF-32, big-endian
FF FE 00 00 | UTF-32, little-endian
FE FF | UTF-16, big-endian
FF FE | UTF-16, little-endian
EF BB BF | UTF-8
Таким образом, вы можете увидеть, как \xef\xbb\xbf
соответствует EF BB BF
UTF-8
Байты спецификации из приведенной выше таблицы.
Использование GNU sed
(в Linux или Cygwin):
# Removing BOM from all text files in current directory:
sed -i '1 s/^\xef\xbb\xbf//' *.txt
На FreeBSD:
sed -i .bak '1 s/^\xef\xbb\xbf//' *.txt
Преимущество использования GNU или FreeBSD sed
: -i
Параметр означает "на месте" и будет обновлять файлы без необходимости перенаправления или странных уловок.
На Mac:
это awk
Решение в другом ответе работает, но sed
Команда выше не работает. По крайней мере, на Mac (Сьерра) sed
документация не упоминает поддержку шестнадцатеричного выхода из аля \xef
,
Подобный трюк может быть достигнут с любой программой, если sponge
инструмент от moreutils:
awk '…' INFILE | sponge INFILE
Не awk, но проще:
tail -c +4 UTF8 > UTF8.nobom
Чтобы проверить спецификацию:
hd -n 3 UTF8
Если спецификация присутствует, вы увидите: 00000000 ef bb bf ...
В дополнение к преобразованию концов строк CRLF в LF, dos2unix
также удаляет спецификации:
dos2unix *.txt
dos2unix
также преобразует файлы UTF-16 с спецификацией (но не файлы UTF-16 без спецификации) в UTF-8 без спецификации:
$ printf '\ufeffä\n'|iconv -f utf-8 -t utf-16be>bom-utf16be
$ printf '\ufeffä\n'|iconv -f utf-8 -t utf-16le>bom-utf16le
$ printf '\ufeffä\n'>bom-utf8
$ printf 'ä\n'|iconv -f utf-8 -t utf-16be>utf16be
$ printf 'ä\n'|iconv -f utf-8 -t utf-16le>utf16le
$ printf 'ä\n'>utf8
$ for f in *;do printf '%11s %s\n' $f $(xxd -p $f);done
bom-utf16be feff00e4000a
bom-utf16le fffee4000a00
bom-utf8 efbbbfc3a40a
utf16be 00e4000a
utf16le e4000a00
utf8 c3a40a
$ dos2unix -q *
$ for f in *;do printf '%11s %s\n' $f $(xxd -p $f);done
bom-utf16be c3a40a
bom-utf16le c3a40a
bom-utf8 c3a40a
utf16be 00e4000a
utf16le e4000a00
utf8 c3a40a
Я знаю, что этот вопрос был адресован Unix/ Linux, но подумал, что стоит упомянуть хороший вариант для Unix-оспариваемых (в Windows, с пользовательским интерфейсом).
Я столкнулся с той же проблемой в проекте WordPress (спецификация вызывала проблемы с RSS-фидом и проверкой страниц), и мне пришлось просмотреть все файлы в довольно большом дереве каталогов, чтобы найти тот, который был с BOM. Нашел приложение под названием Replace Pioneer и в нем:
Batch Runner -> Search (чтобы найти все файлы в подпапках) -> Replace Template -> Binary remove BOM (для этого есть готовый шаблон поиска и замены).
Это было не самое элегантное решение, и оно требовало установки программы, что является недостатком. Но как только я узнал, что происходит вокруг меня, это сработало как шарм (и нашел 3 файла из примерно 2300, которые были в спецификации).