Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将BOM表添加到UTF-8文件_Utf 8_Batch File_Scripting_Byte Order Mark - Fatal编程技术网

将BOM表添加到UTF-8文件

将BOM表添加到UTF-8文件,utf-8,batch-file,scripting,byte-order-mark,Utf 8,Batch File,Scripting,Byte Order Mark,我正在搜索一个脚本(没有成功),它可以作为一个批处理文件工作,如果没有BOM表,我可以在UTF-8文本文件前面添加BOM表 它所使用的语言(perl、python、c、bash)和它所使用的操作系统对我来说都不重要。我可以使用各种各样的计算机 我发现有很多脚本可以执行相反的操作(去掉BOM表),这听起来有点愚蠢,因为如果没有BOM表,许多Windows程序在读取UTF-8文本文件时都会遇到问题 我错过了显而易见的机会吗 谢谢 我觉得这很简单。假设文件始终为UTF-8(您没有检测到编码,您知道编码

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

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

我发现有很多脚本可以执行相反的操作(去掉BOM表),这听起来有点愚蠢,因为如果没有BOM表,许多Windows程序在读取UTF-8文本文件时都会遇到问题

我错过了显而易见的机会吗


谢谢

我觉得这很简单。假设文件始终为UTF-8(您没有检测到编码,您知道编码):

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


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

我使用'file'命令和's'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
#/垃圾箱/垃圾箱
如果[$#-eq 0]
然后
回显使用$0文件。。。
出口1
fi
对于“$@”中的文件
做
回显“#处理:$file”1>&2
如果[!-f“$file”]
然后
echo不是文件:“$file”1>&2
出口1
fi
类型=`file-<“$file”|剪切-d:-f2`
如果回显“$TYPE”| grep-q”(带BOM)'
然后
echo“#$文件已经有BOM表,正在跳过。”1>&2
其他的
(mv“${file}”“${file}”~&&uconv-f utf-8-t utf-8——添加签名<“${file}”>“${file}”)| |(回显错误处理“$file”1>&2;退出1)
fi
完成

编辑:
mv
参数周围添加引号。谢谢@DirkR,很高兴这个脚本非常有用

我根据的代码创建了一个脚本。

签出使用此脚本的示例。

(答案基于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是不同的(否则请检查)

我找到的最简单的方法是

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

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

printf '\xEF\xBB\xBF' | cat - source.txt > source-with-bom.txt
cat-
位表示连接到从print命令导入的
source.txt
的前面。在OS X和Ubuntu上测试。

在VBA Access中:

    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+cygwin上非常有用),mv也需要“”,否则它将无法处理带有空格的路径名。剧本不错,谢谢!出现了一个问题,关于如何在子目录上使用它……您可能可以这样使用它:
find-键入f-print0 | xargs-0 addbom.sh
,它将调用所有子目录的addbom.sh脚本。对于UTF-8,请使用
\xef\xbb\xbf
;对于UTF-16 little-endian,请使用
\xff\xfe
;对于UTF-16 big-endian,请使用
\xfe\xff
。看,这在Mac上对我不起作用。命令行
sed-i'1s/^/\xef\xbb\xbf/'temp.csv
给了我
sed:1:“temp.csv”:未定义的标签“emp.csv”
@PerLundberg您可以尝试进行故障排除。。尝试
sed'1s/asdfasdfasdf/'blah.csv
缺少-i将使其非常安全,因为它保持输入文件不变,并将结果输出到控制台。该行应查看第一行,搜索字符串asdfasdfasdf,并将其替换为nothing,即删除该字符串。然后尝试将其设置为
^adsfasdf
^
标记行的开头,可能是由于某种原因导致了问题。也许你需要在sed中使用一个开关,让它像maybe-E一样使用
^
,虽然我不知道。@PerlLundberg我在macOS 10.13中也遇到了同样的问题,在做了很多修改后,我发现
sed-I'$'1s/^/\xef\xbb\xbf/'foo-*
可以工作