Использование awk для удаления знака Byte-order

Как бы выглядел скрипт awk (предположительно однострочный) для удаления спецификации ?

Спецификация:

  • распечатать каждую строку после первого ( NR > 1 )
  • для первой строки: если она начинается с #FE #FF или #FF #FE , удалите их и распечатайте остальные

Попробуй это:

 awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE 

На первой строке (строке) удалите символы спецификации. Распечатайте каждую запись.

Или немного короче, используя знания о том, что действие по умолчанию в awk должно печатать запись:

 awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE 

1 – кратчайшее условие, которое всегда оценивается как true, поэтому каждая запись печатается.

Наслаждайтесь!

– ДОБАВЛЕНИЕ –

Частота юникодного байта (BOM) FAQ включает в себя следующую таблицу с указанием точных байтов спецификации для каждой кодировки:

 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 соответствует \xef\xbb\xbf UTF-8 EF BB BF из приведенной выше таблицы.

Использование 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: параметр -i означает «на месте» и будет обновлять файлы без необходимости перенаправления или странных трюков.

На Mac:

Это awk решение в другом ответе работает , но команда sed выше не работает. В документации по Mac (Sierra) sed не упоминается поддержка шестнадцатеричного экранирования ala \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 с BOM (но не файлы 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-challenge (на окнах с пользовательским интерфейсом).
Я столкнулся с той же проблемой в проекте WordPress (спецификация вызывала проблемы с rss-каналом и проверкой страницы), и мне пришлось изучить все файлы в довольно большом дереве каталогов, чтобы найти тот, который был с спецификацией. Нашел приложение под названием Replace Pioneer и в нем:

Batch Runner -> Поиск (чтобы найти все файлы в подпапках) -> Replace Template -> Binary удалить спецификацию (для этого есть готовый шаблон поиска и замены).

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