我正在搜索(未成功)腳本,該腳本將作爲批處理文件工作,並允許我在文件沒有BOM的情況下預先加載帶有BOM的UTF-8文本文件。將BOM添加到UTF-8文件
無論它寫入的語言(perl,python,c,bash)還是它對我來說都很重要的操作系統。我可以訪問各種各樣的電腦。
我發現很多腳本可以做相反的操作(剝離BOM),這對我來說聽起來很愚蠢,因爲許多Windows程序在閱讀UTF-8文本文件時會遇到麻煩,如果它們沒有BOM。
我有沒有想到明顯? 謝謝!
我正在搜索(未成功)腳本,該腳本將作爲批處理文件工作,並允許我在文件沒有BOM的情況下預先加載帶有BOM的UTF-8文本文件。將BOM添加到UTF-8文件
無論它寫入的語言(perl,python,c,bash)還是它對我來說都很重要的操作系統。我可以訪問各種各樣的電腦。
我發現很多腳本可以做相反的操作(剝離BOM),這對我來說聽起來很愚蠢,因爲許多Windows程序在閱讀UTF-8文本文件時會遇到麻煩,如果它們沒有BOM。
我有沒有想到明顯? 謝謝!
我覺得很簡單。假設該文件是總是 UTF-8(你沒有檢測到編碼,你知道編碼):
閱讀前三個字符。將它們與UTF-8 BOM序列進行比較(維基百科說它是0xEF,0xBB,0xBF)。 如果相同,則將它們打印在新文件中,然後將其他所有內容從原始文件複製到新文件。 如果不同,首先打印BOM,然後打印三個字符,然後只打印原始文件中的所有內容到新文件。
在C中,fopen/fclose/fread/fwrite應該足夠了。
我用'file'命令和ICU的'uconv'命令寫了這個addbom.sh。
#!/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
編輯:各地mv
參數加引號。謝謝@DirkR,很高興這個腳本非常有幫助!
我想我不會寫這樣的小事我自己,但因爲我也需要做一些字符轉化,那就是:
#!/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
爲正確的值。
(由yingted基於https://stackoverflow.com/a/9815107/1260896答案)
要BOM表添加到所有以「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是不同的(否則檢查How can I re-add a unicode byte order marker in linux?)
對於UTF-8,使用'\ xef \ xbb \ xbf';對於UTF-16 little-endian使用'\ xff \ xfe';對於UTF-16 big-endian使用'\ xfe \ xff'。請參閱https://www.w3.org/International/questions/qa-byte-order-mark – 2016-05-11 12:25:52
這在Mac上不適用於我。命令行'sed -i'1s/^/\ xef \ xbb \ xbf /'temp.csv'給了我'sed:1:「temp.csv」:undefined label'emp.csv'' – 2017-11-22 07:20:10
@PerLundberg你可以嘗試排除故障..嘗試'sed'1s/asdfasdfasdf //'blah.csv'缺少-i將使它非常安全,因爲它保持輸入文件不變並將結果輸出到控制檯。該行應該查看第一行,搜索字符串asdfasdfasdf並將其替換爲無,即刪除該字符串。然後嘗試使它成爲'^ adsfasdfasdf'這個'^'標誌着行的開始,也許這是由於某種原因造成的問題。也許你需要使用帶sed的開關來讓它像使用'^'一樣,儘管我不知道。 – barlop 2017-12-12 21:26:19
我發現最簡單的方法是
#!/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上工作,以及
請注意,它假定該文件還沒有BOM (!)
絕對完美!比我帶來的好多了。 非常感謝。 – Stephane 2010-07-21 03:16:02
「$ @」優於$ *。這將保持空間的參數(在Windows + cygwin上有用) – mcoolive 2014-08-13 09:20:33
@mcoolive謝謝 – 2014-08-13 17:21:50