我正在搜索(但没有成功)一个脚本,它可以作为批处理文件工作,并允许我在没有 BOM 的 UTF-8 文本文件前面添加 BOM。
它所使用的语言(perl、python、c、bash)和它运行的操作系统对我来说都不重要。我可以使用各种计算机。
我发现很多脚本可以做相反的事情(去掉 BOM),这在我看来有点愚蠢,因为如果没有 BOM,许多 Windows 程序在读取 UTF-8 文本文件时会遇到问题。
我错过了显而易见的事情吗?
谢谢!
我发现的最简单的方法是
#!/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 (!)
我使用“file”命令和 ICU 的“uconv”命令编写了这个 addbom.sh。
#!/bin/sh
if [ $# -eq 0 ]
then
echo usage $0 files ...
exit 1
fi
for file in "$@"
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,很高兴这个脚本如此有帮助!
(答案基于 https://stackoverflow.com/a/9815107/1260896 by yingted)
要将 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 是不同的(否则请检查 如何在 Linux 中重新添加 unicode 字节顺序标记?)
作为 Yaron U. 解决方案的改进,您可以在一行中完成所有操作:
printf '\xEF\xBB\xBF' | cat - source.txt > source-with-bom.txt
cat -
位表示连接到 source.txt
的前面,这些内容是从 print 命令通过管道传入的。在 OS X 和 Ubuntu 上测试。
我觉得很简单。假设文件是alwaysUTF-8(你没有检测到编码,你知道编码):
读出前三个字符。将它们与 UTF-8 BOM 序列进行比较(维基百科说它是 0xEF、0xBB、0xBF)。 如果相同,则在新文件中打印它们,然后将原始文件中的其他所有内容复制到新文件中。 如果不同,请先打印 BOM,然后打印三个字符,然后再打印从原始文件到新文件的所有其他内容。
在 C 语言中,fopen/fclose/fread/fwrite 就足够了。
用记事本打开。单击另存为。在编码下,选择“UTF-8(BOM)”(这是在普通的“UTF-8”下)。
在 VBA 访问中:
Dim name As String
Dim tmpName As String
tmpName = "tmp1.txt"
name = "final.txt"
Dim file As Object
Dim finalFile As Object
Set file = CreateObject("Scripting.FileSystemObject")
Set finalFile = file.CreateTextFile(name)
'Add BOM
finalFile.Write Chr(239)
finalFile.Write Chr(187)
finalFile.Write Chr(191)
'transfer text from tmp to final file:
Dim tmpFile As Object
Set tmpFile = file.OpenTextFile(tmpName, 1)
finalFile.Write tmpFile.ReadAll
finalFile.Close
tmpFile.Close
file.DeleteFile tmpName
这是我在 Windows 中用于此目的的批处理文件。
/p=
部分应使用 ANSI (Windows-1252) 编码保存。
@echo off
if [%~1]==[] goto usage
if not exist "%~1" goto notfound
setlocal
set /p AREYOUSURE="Adding UTF-8 BOM to '%~1'. Are you sure (Y/[N])? "
if /i "%AREYOUSURE%" neq "Y" goto canceled
:: Main code is here. Create a temp file containing the BOM, then append the requested file contents, and finally overwrite the original file
(echo|set /p=)>"%~1.temp"
type "%~1">>"%~1.temp"
move /y "%~1.temp" "%~1" >nul
@echo Added UTF-8 BOM to "%~1"
pause
exit /b 0
:usage
@echo Usage: %0 ^<FILE_NAME^>
goto end
:notfound
@echo File not found: "%~1"
goto end
:canceled
@echo Operation canceled.
goto end
:end
pause
exit /b 1
您可以将文件保存为例如
C:\addbom.bat
并使用以下 .reg
文件将其添加到所有文件的右键单击上下文菜单中:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\Shell\Add UTF-8 BOM]
[HKEY_CLASSES_ROOT\*\Shell\Add UTF-8 BOM\command]
@="C:\\addbom.bat \"%1\""
这是一种单行解决方案,无需任何临时文件即可本地运行:
Mac操作系统:
sed -i '' '1s/^/\xEF\xBB\xBF/' filename.txt
其他 Unix 系统:
sed -i '1s/^/\xEF\xBB\xBF/' filename.txt
MacOS 在其
-i
实现中使用 sed
函数的方式有一个怪癖,因为它需要提供备份文件名,但您可以使用上面的 ''
参数绕过它。
注意:ChatGPT 4 对此有所帮助。