行末出现'^M'字符

104

当我在Unix环境下运行特定的SQL脚本时,我会看到每行末尾输出到命令行上的SQL脚本都有一个'^M'字符。
我不知道这个SQL脚本最初是在哪个操作系统上创建的。

这是什么原因造成的?如何解决这个问题?

17个回答

82

这是由于DOS / Windows的换行符引起的。就像Andy Whitfield所说,Unix命令dos2unix可以帮助解决此问题。如果您想获得更多信息,可以阅读该命令的手册页面。


3
在某些系统(如Ubuntu)中,该命令的名称为“fromdos”。 - bobwienholt
6
如果你已经安装了Homebrew,那么你可以通过brew install dos2unix轻松地在OSX上获取这个工具。 - philipp

81

通过运行以下命令,在 vi中修复行末结束符:

:set fileformat=unix

:w


2
这是一个非常棒的答案。非常感谢。(省去了安装dos2unix的步骤,这是一个我可能只会用一次的工具) - James
3
由于某些原因,这不能去除 ^M。参考文件:/etc/timidity/fluidr3_gm.cfg - phil294

41

问题的原因是基于 Windows 操作系统和基于 Unix 操作系统的行尾符存储方式不同。

由于其 DOS 的遗产,基于 Windows 的操作系统将行尾符存储为一对字符 - 0x0D0A(回车 + 换行)。而基于 Unix 的操作系统只使用 0x0A(一个换行符)。你看到的^M0x0D(一个回车符)的可视化表示。

dos2unix可以帮助解决这个问题。你可能还需要调整脚本源以适应 Unix 环境。


我不会说当前版本的Windows具有任何DOS遗产。但它们仍然存在兼容性限制。 - Joey
这是一种简单的方法,就是使用自动转换工具。谢谢。 - Pjl
但是为什么会出现 ^M?为什么有 '^'?为什么有 'M'? - 1737973
1
因为它是一个“控制字符”。“^”是单击控制键的可视化表示。在其下面只是特定的字节,而“^”是编辑器表示它们的方式。 - Hejazzman
1
赞同这个清晰且信息量充足的答案。顺便说一下,我刚试了 Excel 的所有不同 CSV 选项“另存为...”,但它们都会产生 \r,我可以通过在 Linux 上使用 cat -e filename.csv 看到 ^M。还尝试了 Apache OpenOffice 中的 Calc,它现在在 Microsoft Store 上也有,结果相同。结论是,我将使用 Excel 或 Calc 进行编辑方便,并在 git commit 之前使用 dos2unix 去掉 ^M - Nagev

25
最简单的方法是使用vi。虽然可能听起来很糟糕,但它很简单,并且已经安装在大多数UNIX环境中。^M是来自Windows / DOS环境的新行。 从命令提示符输入:$ vi filename 然后按 ":" 进入命令模式。
全局搜索和替换是 :%s/^M//g "按住控制键,然后按V再按M",这将用空白替换^M。
最后写入并退出请输入 ":wq" 完成!

1
如何在emacs中进行替换? - herbertD
4
感谢您对如何键入^M字符的说明!我会将其替换为\r。 所以我执行了命令::%s/^M/\r/g - aharris88
这对于在Windows子系统中运行的nvim无效。 - 71GA
@herbertD,也许这个对于Emacs有所帮助:https://www.emacswiki.org/emacs/DosToUnix。dos2unix也会默认安装在Doom Emacs中。 - eho

14

尝试使用dos2unix去掉^M字符。


10
在Vi编辑器中,执行:%s/^M//g 要获取^M字符,按住CTRL键,然后按下VM(同时按住控制键),^M字符将出现。这将查找所有出现并用空格替换它们。

2
将 ^M 替换为 Unix 友好的换行符::%s/^M/\r/g - Gary Oak

8

该SQL脚本最初是在Windows操作系统上创建的。'^M'字符是Windows和Unix关于行尾字符使用不同想法的结果。你可以在命令行中使用Perl来解决此问题。

perl -pie 's/\r//g' filename.txt

当然,你可以使用 Perl,但是你会建议使用 Perl 而不是 dos2unix 吗? - Thomas Owens
2
我只是提供一个替代方案,因为已经有四个人建议使用dos2unix。 - Bill the Lizard
2
是的,我发现这很有用,因为我在一个后退的工作站上工作,在一个史前的IT部门的办公室里。除了我使用了一种变化:perl -pi -e "s/\x0D/\n/g" file.csv - Rimian

7

^M通常是由Windows操作系统的换行符引起的,在Unix上翻译后看起来像^M。dos2unix命令可以很好地删除它们。

dos2unix [选项] [-c 转换模式] [-o 文件 ...] [-n 输入文件 输出文件 ...]


5

使用标准工具如seddos2unix命令的另一种选择。

例如,将DOS格式转换为Unix格式:

sed 's/\r$//' dos.txt > unix.txt

Unix转Dos:

sed 's/$/\r/' unix.txt > dos.txt

5
C:\tmp\text>dos2unix hello.txt helloUNIX.txt

Sed更加广泛可用,即使未安装dos2unix也可以执行此类操作。

C:\tmp\text>sed s/\r// hello.txt > helloUNIX.txt  

您可以尝试使用 tr 标签:
cat hello.txt | tr -d \r > helloUNIX2.txt  

以下是结果:
C:\tmp\text>dumphex hello.txt  
00000000h: 48 61 68 61 0D 0A 68 61 68 61 0D 0A 68 61 68 61 Haha..haha..haha  
00000010h: 0D 0A 0D 0A 68 61 68 61 0D 0A                   ....haha..  

C:\tmp\text>dumphex helloUNIX.txt  
00000000h: 48 61 68 61 0A 68 61 68 61 0A 68 61 68 61 0A 0A Haha.haha.haha..  
00000010h: 68 61 68 61 0A                                  haha.  

C:\tmp\text>dumphex helloUNIX2.txt  
00000000h: 48 61 68 61 0A 68 61 68 61 0A 68 61 68 61 0A 0A Haha.haha.haha..  
00000010h: 68 61 68 61 0A                                  haha.  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接