$ file test.xml
test.xml: XML 1.0 document, UTF-8 Unicode (with BOM) text, with very long lines
#1 楼
如果不确定文件是否包含UTF-8 BOM表,则此操作(假设sed
的GNU实现)将删除BOM表(如果存在),否则将不进行任何更改。 /> sed '1s/^\xEF\xBB\xBF//' < orig.txt > new.txt
还可以使用
-i
选项覆盖现有文件:sed -i '1s/^\xEF\xBB\xBF//' orig.txt
如果使用的是BSD版本的
sed
(例如macOS),那么您需要让bash转义: sed $'1s/\xef\xbb\xbf//' < orig.txt > new.txt
评论
这在utf8语言环境中可能不起作用,但是在c或posix之前添加语言环境覆盖将始终有效。
–躲藏
17年7月23日在15:29
@hildred我已经使用en_US.UTF-8语言环境对其进行了测试,并且可以正常工作。什么时候会失败?
– m13r
17年7月24日在6:55
@ m13r,取决于sed和compile选项的版本。在失败的情况下,具有Unicode字符类的sed的非常新版本将把三个字节的序列作为单个字符引入,这与三个字符序列不匹配。但是,在这种情况下,您可以进行16位字符匹配。但是,这是一个新功能,并不普遍存在。如果要测试,建议编译最新版本。
–躲藏
17年7月24日在16:25
要修复它以使其与启用unicode的sed一起工作,请执行LC_ALL = C sed'1s / ^ \ xEF \ xBB \ xBF //'
–约书亚
17年7月24日在17:41
@ mazunki,1s /表示仅搜索第一行;其他行不受影响。 ^表示仅在(第一)行的开头匹配。 \ xEF \ xBB \ xBF是UTF-8 BOM(转义的十六进制字符串)。 //表示不作任何替换。我可以在末尾添加1(表示1s / ^ xEF \ xBB \ xBF // 1),这意味着仅匹配该行上第一次出现的模式。但是,由于搜索使用^锚定,因此没有任何区别。如果文件在第一行的开头没有BOM,则该模式将不匹配,因此不会进行任何更改。
– CSM
19-10-27在18:47
#2 楼
在UTF-8中,BOM没有意义。这些通常是由Microsoft操作系统上的伪造软件错误地添加的。评论
我同意UTF-8编码的BOM没有意义,但不管您相信与否,很多人认为这是一个有助于将UTF-8与其他8位编码区分开的好主意。因此,这是一个品味问题。 Windows记事本是故意添加的BOM。
– JohanMyréen
17年7月23日在14:02
如果上下文只是如何删除上下文的问题,那么有意义与否有什么关系?根据Wikipedia的介绍,记事本要求BOM将该文件识别为UTF-8,并且Google Docs在将文件导出为文本时也会添加它。我怀疑他们都错误地做到了。
–ilkkachu
17年7月23日在14:09
有没有一种方法不转换行尾,而只使用dos2unix删除BOM?
– m13r
17年7月25日在7:55
@ m13r然后在此答案中使用sed脚本。这将仅删除物料清单(如果存在),则不会更改任何其他内容。
–艾萨克
17年7月26日在5:51
@JohanMyréen是的,但称它们为UTF-8是不正确的。它们不是UTF-8文件。它们是带有BOM的UTF-8文件,这是另一种文件格式。我想那些Windows怪胎会不满意被称为MSOffice文件的ODT文件:)
– 9ilsdx 9rvj 0lo
18年11月9日在9:47
#3 楼
使用VIM在VIM中打开文件:
vi text.xml
删除BOM表编码:
:set nobomb
保存并退出:
:wq
对于非交互式解决方案,请尝试以下命令行:
< preclass =“ lang-bsh prettyprint-override”>
vi -c ":set nobomb" -c ":wq" text.xml
应从命令行删除BOM,保存文件并退出。
评论
奇怪的是,在Mac上使用vim 8,我有一个Excel制作的csv utf-8文件,它以
– dlamblin
19-10-9在21:11
这比在大型文件上拖尾要快得多。
–user239558
19/12/2在20:14
#4 楼
可以使用tail
命令从文件中删除BOM:tail -c +4 withBOM.txt > withoutBOM.txt
评论
为什么是4? BOM有3个字节。
–deviantfan
17年7月23日在17:12
@deviantfan这就是为什么要跳过第4个字节的原因。
–StéphaneChazelas
17年7月23日在18:33
尾部是否使用基于1的索引? WTF!
– CodesInChaos
17年7月23日在19:31
@ CodesInChaos,tail -c -1或tail -c 1(通常用于tail)是从最后一个字节开始的内容,tail -c +1从第一个字节开始。 tail -c 0 / tail -c +0会更不直观。
–StéphaneChazelas
17年7月23日在23:05
@deviantfan:(dd bs = 1 count = 3 of = / dev / null; cat)<输入>输出。或使用GNU(头-c3> / dev / null; cat)-即使在UTF8或其他非单字节语言环境中也是如此; GNU head执行'char'= byte。
–dave_thompson_085
17年7月24日在6:16
#5 楼
您可以使用LANG=C LC_ALL=C sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- filename
从文件的开头删除字节序标记(如果有的话),以及将任何CR LF换行符仅转换为LF。
LANG=C LC_ALL=C
告诉外壳程序您希望命令在默认的C语言环境(也称为默认的POSIX语言环境)中运行,其中构成字节顺序标记的三个字节被视为字节。 sed的-i
选项表示就地。如果使用-i.old
,那么sed将原始文件另存为filename.old
,并将新文件(如果有修改,另存为)另存为filename
。例如,作为#!/bin/dash
export LANG=C LC_ALL=C
if [ $# -gt 0 ]; then
for FILE in "$@" ; do
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$FILE" || exit 1
done
else
exec sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//'
fi
,这样,如果我需要将其应用于所有C源文件和标头(例如,我的旧代码来自MS-DOS时代,例如!),我只运行
find . -name '*.[CHch]' -print0 | xargs -r0 ~/bin/ms-fix
,或者,如果我只想查看这样的文件,而无需修改它,则可以运行
~/bin/ms-fix < filename | less
,在我的UTF-8终端上看不到难看的
~/bin/fix-ms
。评论
为什么不简单地sed -e's / \ r $ //; 1 s / ^ \ xef \ xbb \ xbf //'-i-“ $ @”?
–StéphaneChazelas
17年7月24日在14:02
@StéphaneChazelas:因为如果替换出现问题,我希望脚本立即退出,它可以sed -e's / \ r $ //; 1 s / ^ \ xef \ xbb \ xbf //'-i-“ $ @”不起作用;它确实返回退出代码,但是在退出之前,它会处理参数列表中列出的所有文件。
–动物
17年7月24日在14:24
@StéphaneChazelas:文件名之前的-当然很重要:如果没有文件名,则sed可以将文件名以短划线开头。我将这些内容编辑成答案;谢谢你的提醒!
–动物
17年7月24日在14:27
#6 楼
我在常规上使用vim一线纸:vim --clean -c 'se nobomb|wq' filename
vim --clean -c 'bufdo se nobomb|wqa' filename1 filename2 ...
评论
使用VIM的前个性也应该可以实现这一点。
– JdeBP
20-10-7在9:46
#7 楼
我有一个略有不同的问题,正把它放在这里给像我一样,最终在这里得到充满ZERO WIDTH NO-BREAK SPACE
个字符的数据(当它们是文件的第一个字符时被称为Byte Order Mark
)的人。通过复制出grafana查询指标字段来获取此数据,并且它在一行中有多个(17)\xef\xbb\xbf
序列(在vim中显示为rate<feff>(<feff>node<feff>{<feff>job<feff>
),只有81个实际字符。略微:LANG=C LC_ALL=C sed -e 's/\xef\xbb\xbf//g'
,而
:set nobomb
中的vim
只会删除文件中的第一个。尝试过: ,但它们仍然在那里(即使在写完之后...)
#8 楼
最近,我发现了这个小巧的命令行工具,它可以在任意UTF-8编码文件上添加或删除BOM:UTF BOM Utils(github上的新链接)小缺点,您只能下载纯C ++源代码。您必须创建makefile(例如,使用CMake)并自行编译,该页面没有提供二进制文件。
评论
相似:具有BOM的AWK:是否有任何很酷的方法通过正则表达式处理Unicode BOM?几个月前,我已经做了一个非常简单的工具:oskog97.com/read/?path=/small-scripts/killbom&referer = / ...如果在/ usr / local / bin中安装类似的东西,可能值得您有许多带有BOM的UTF-8编码文件。
奇怪的是,交叉发布在stackoverflow.com/questions/45240387/…