将 BOM 添加到 UTF-8 文件

Posted

技术标签:

【中文标题】将 BOM 添加到 UTF-8 文件【英文标题】:Adding BOM to UTF-8 files 【发布时间】:2011-03-08 19:58:51 【问题描述】:

我正在搜索(没有成功)一个脚本,它可以作为批处理文件使用,如果没有 BOM,我可以在 UTF-8 文本文件前面添加一个 BOM。

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

我发现很多脚本可以做相反的事情(剥离 BOM),这听起来有点傻,因为许多 Windows 程序如果没有物料清单。

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

谢谢!

【问题讨论】:

【参考方案1】:

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

【讨论】:

绝对完美!比我自带的好多了。非常感谢。 "$@" 比 $* 这里好。这将保留带空格的参数(在 windows+cygwin 上很有用) mv 也需要 "" 否则它不适用于带有空格的路径名。不错的脚本,谢谢! 出现了一个问题,关于如何在子目录上使用它……你可以这样使用它:find . -type f -print0 | xargs -0 addbom.sh 它将为所有子目录调用 addbom.sh 脚本。【参考方案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 上运行

请注意,它假定文件还没有 BOM (!)

【讨论】:

【参考方案3】:

(根据 yingtedhttps://***.com/a/9815107/1260896 回答)

要向所有以“foo-”开头的文件添加 BOM,您可以使用sedsed 可以选择进行备份。

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 大端使用 \xfe\xff。见w3.org/International/questions/qa-byte-order-mark 这对我在 Mac 上不起作用。命令行sed -i '1s/^/\xef\xbb\xbf/' temp.csv给了我sed: 1: "temp.csv": undefined label 'emp.csv' @PerLundberg 您可以尝试进行故障排除.. 尝试sed '1s/asdfasdfasdf//' blah.csv 缺少 -i 将使其非常安全,因为它使输入文件保持不变并将结果输出到控制台。该行应查看第一行,搜索字符串 asdfasdfasdf 并将其替换为空,即删除该字符串。然后尝试将其设置为^adsfasdfasdf ^ 标记行的开头,也许这由于某种原因导致了问题。也许你需要使用带有 sed 的开关来让它使用 ^ 就像也许 -E 虽然我不知道。 @PerlLundberg 我在 macOS 10.13 上遇到了同样的问题,经过大量的摆弄,我发现 sed -i '' $'1s/^/\xef\xbb\xbf/' foo-* 有效【参考方案4】:

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

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

cat - 位表示连接到 source.txt 的前面,从打印命令中输入的内容。在 OS X 和 Ubuntu 上测试。

【讨论】:

【参考方案5】:

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

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

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

【讨论】:

【参考方案6】:

我已经根据Steven R. Loomis 的代码创建了一个脚本。 https://github.com/Vdragon/addUTF-8bomb

结帐https://github.com/Vdragon/C_CPP_project_template/blob/development/Tools/convertSourceCodeToUTF-8withBOM.bash.sh 以使用此脚本为例。

【讨论】:

【参考方案7】:

在 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

【讨论】:

以上是关于将 BOM 添加到 UTF-8 文件的主要内容,如果未能解决你的问题,请参考以下文章

求个给UTF-8文件批量去UTF-8 BOM头的批处理,去掉BOM后覆盖原来的文件,最好我可以自己添加多个文件名称!

linux给一个文件头部添加内容,给UTF-8添加BOM头

在没有bom的情况下以utf-8保存文件

将 UTF-8 BOM 添加到字符串/Blob

使用 fputcsv 将 BOM 添加到 CSV 文件

PHP 下载文件时自动添加bom头的方法