Подтвердить что ты не робот

Добавление спецификации в файлы UTF-8

Я ищу (без успеха) script, который будет работать в виде пакетного файла и позволит мне добавить текстовый файл UTF-8 с спецификацией, если он не имеет его.

Ни язык, на котором он написан (perl, python, c, bash), либо OS он работает по мне. У меня есть доступ к широкому спектру компьютеров.

Я нашел много script, чтобы сделать обратное (разделите спецификацию), что звучит для меня как-то глупо, так как многие программы Windows будут иметь проблемы с чтением текстовых файлов UTF-8, если они не имеют спецификацию.

Я пропустил очевидное? Спасибо!

4b9b3361

Ответ 1

Я написал этот addbom.sh с помощью команды 'file' и ICU 'uconv'.

#!/bin/sh

if [ $# -eq 0 ]
then
        echo usage $0 files ...
        exit 1
fi

for file in "[email protected]"
do
        echo "# Processing: $file" 1>&2
        if [ ! -f "$file" ]
        then
                echo Not a file: "$file" 1>&2
                exit 1
        fi
        TYPE=`file - < "$file" | cut -d: -f2`
        if echo "$TYPE" | grep -q '(with BOM)'
        then
                echo "# $file already has BOM, skipping." 1>&2
        else
                ( mv "${file}" "${file}"~ && uconv -f utf-8 -t utf-8 --add-signature < "${file}~" > "${file}" ) || ( echo Error processing "$file" 1>&2 ; exit 1)
        fi
done

edit: Добавлены цитаты вокруг аргументов mv. Спасибо @DirkR и рад, что этот script был настолько полезен!

Ответ 2

Самый простой способ, который я нашел для этого, -

#!/usr/bin/env bash

#Add BOM to the new file
printf '\xEF\xBB\xBF' > with_bom.txt

# Append the content of the source file to the new file
cat source_file.txt >> with_bom.txt

Я знаю, что он использует внешнюю программу (cat)... но он легко выполнит работу в bash

Протестировано на osx, но должно работать и с linux

ЗАМЕЧАНИЕ, что он предполагает, что файл еще не имеет спецификации (!)

Ответ 3

(Ответ основан на fooobar.com/questions/197798/... yingted)

Чтобы добавить спецификации к всем файлам, начинающимся с "foo-", вы можете использовать sed. sed имеет возможность сделать резервную копию.

sed -i '1s/^\(\xef\xbb\xbf\)\?/\xef\xbb\xbf/' foo-*

Если вы точно знаете, что BOM уже нет, вы можете упростить команду:

sed -i '1s/^/\xef\xbb\xbf/' foo-*

Убедитесь, что вам нужно установить UTF-8, потому что UTF-16 отличается (в противном случае проверьте Как я могу повторно добавить маркер порядка байтов в юникоде в Linux?)

Ответ 4

Я нахожу это довольно простым. Предполагая, что файл всегда UTF-8 (вы не обнаруживаете кодировку, вы знаете кодировку):

Прочитайте первые три символа. Сравните их с последовательностью BAT UTF-8 (wikipedia говорит, что это 0xEF, 0xBB, 0xBF). Если это то же самое, напечатайте их в новом файле, а затем скопируйте все остальное из исходного файла в новый файл. Если он отличается, сначала распечатайте спецификацию, затем распечатайте три символа и только затем распечатайте все остальное из исходного файла в новый файл.

В C, fopen/fclose/fread/fwrite должно быть достаточно.

Ответ 6

Я думал, что мне не придется писать такую ​​тривиальную вещь сам, но так как мне также нужно было преобразовать кодировку, вот она:

#!/usr/bin/python
import os
import sys
import codecs

INPUT_ENCODING = codecs.BOM_UTF16_LE  # 'utf_16_le'
OUTPUT_ENCODING = 'utf-8-sig'         # is there a constant for this??

if len(sys.argv) == 1:
    print 'Usage:\n\t%s <filename.txt>' % sys.argv[0]
    sys.exit(-1)

output_file = os.path.splitext(os.path.split(sys.argv[1])[-1])[0]
fin = codecs.open(sys.argv[1], 'rb', encoding=INPUT_ENCODING)
fout = codecs.open(output_file + '_utf8bom.txt', 'wb', encoding=OUTPUT_ENCODING)
fout.write(fin.read())
fin.close()
fout.close()

print 'done'

Вызовите его только с именем исходного файла, то есть:

# utf8bom_add.py myfilename.txt

И если вы конвертируете UTF-8 в UTF-8, они меняют INPUT_ENCODING на правильное значение.