向UTF-8文件添加BOM

问题描述 投票:0回答:10

我正在搜索(但没有成功)一个脚本,它可以作为批处理文件工作,并允许我在没有 BOM 的 UTF-8 文本文件前面添加 BOM。

它所使用的语言(perl、python、c、bash)和它运行的操作系统对我来说都不重要。我可以使用各种计算机。

我发现很多脚本可以做相反的事情(去掉 BOM),这在我看来有点愚蠢,因为如果没有 BOM,许多 Windows 程序在读取 UTF-8 文本文件时会遇到问题。

我错过了显而易见的事情吗?

谢谢!

utf-8 batch-file scripting byte-order-mark
10个回答
61
投票

我发现的最简单的方法是

#!/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 (!)


52
投票

我使用“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,很高兴这个脚本如此有帮助!


27
投票

(答案基于 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 字节顺序标记?


24
投票

作为 Yaron U. 解决方案的改进,您可以在一行中完成所有操作:

printf '\xEF\xBB\xBF' | cat - source.txt > source-with-bom.txt

cat -
位表示连接到
source.txt
的前面,这些内容是从 print 命令通过管道传入的。在 OS X 和 Ubuntu 上测试。


3
投票

我觉得很简单。假设文件是alwaysUTF-8(你没有检测到编码,你知道编码):

读出前三个字符。将它们与 UTF-8 BOM 序列进行比较(维基百科说它是 0xEF、0xBB、0xBF)。 如果相同,则在新文件中打印它们,然后将原始文件中的其他所有内容复制到新文件中。 如果不同,请先打印 BOM,然后打印三个字符,然后再打印从原始文件到新文件的所有其他内容。

在 C 语言中,fopen/fclose/fread/fwrite 就足够了。


2
投票

用记事本打开。单击另存为。在编码下,选择“UTF-8(BOM)”(这是在普通的“UTF-8”下)。


1
投票

在 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


0
投票

这是我在 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\""


0
投票

这是一种单行解决方案,无需任何临时文件即可本地运行:

Mac操作系统:

sed -i '' '1s/^/\xEF\xBB\xBF/' filename.txt

其他 Unix 系统:

sed -i '1s/^/\xEF\xBB\xBF/' filename.txt

MacOS 在其

-i
实现中使用
sed
函数的方式有一个怪癖,因为它需要提供备份文件名,但您可以使用上面的
''
参数绕过它。

注意:ChatGPT 4 对此有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.