Добавление спецификации в файлы UTF-8
Я ищу (без успеха) script, который будет работать в виде пакетного файла и позволит мне добавить текстовый файл UTF-8 с спецификацией, если он не имеет его.
Ни язык, на котором он написан (perl, python, c, bash), либо OS он работает по мне. У меня есть доступ к широкому спектру компьютеров.
Я нашел много script, чтобы сделать обратное (разделите спецификацию), что звучит для меня как-то глупо, так как многие программы Windows будут иметь проблемы с чтением текстовых файлов UTF-8, если они не имеют спецификацию.
Я пропустил очевидное?
Спасибо!
Ответы
Ответ 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 должно быть достаточно.
Ответ 5
Я создал script на основе кода Стивена Р. Лумиса.
https://github.com/Vdragon/addUTF-8bomb
Оформить покупку https://github.com/Vdragon/C_CPP_project_template/blob/development/Tools/convertSourceCodeToUTF-8withBOM.bash.sh, например, используя этот script.
Ответ 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
на правильное значение.