行尾的'^ M'字符


99

当我在Unix环境中运行特定的SQL脚本时,我在该SQL脚本的每一行的末尾看到一个'^ M'字符,因为它回显了命令行。我不知道最初在哪个OS上创建SQL脚本。

是什么原因引起的,该如何解决?

Answers:


79

这是由DOS / Windows行尾字符引起的。就像安迪·惠特菲尔德(Andy Whitfield)所说的那样,Unix命令dos2unix将帮助解决该问题。如果需要更多信息,可以阅读该命令的手册页。


3
在某些系统上(例如Ubuntu),此命令的名称为“ fromdos”
bobwienholt

6
brew install dos2unix安装自制软件后,您可以在OSX上轻松获得该工具
philipp 2013年

73

vi通过运行以下命令来修复行尾:

:set fileformat=unix

:w


2
这是一个绝妙的答案。非常感谢。(已保存dos2unix,我可能只使用过一次的工具)
Jamsi 2014年

3
^M由于某些原因,这不会删除。参考文件:/etc/timidity/fluidr3_gm.cfg
phil294 '17

39

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

基于Windows的操作系统,由于它们具有DOS的传统,因此将行尾存储为一对字符- 0x0D0A(回车+换行符)。仅使用基于Unix的操作系统0x0A换行符)。在^M你看到的是一个可视化表示0x0D(一个回车)。

dos2unix将对此有所帮助。您可能还需要将脚本源调整为“ Unix友好”。


我不会说Windows的当前版本具有任何DOS 传统。但是,它们仍然具有兼容性限制。
乔伊(Joey)2013年

这是简单的方法,是您要做一个自动转换工具。感谢的
PJL

但是为什么^M呢?为什么是“ ^”?为什么是“ M”?
1737973

因为它是一个“控制字符”。“ ^”是单击控制键的直观表示。在其仅特定字节的下面,^是编辑器表示它们的方式。
Hejazzman,2015年

24

最简单的方法是使用vi我知道这听起来很糟糕,但是它很简单,并且已经在大多数UNIX环境中安装了。^ M是Windows / DOS环境下的新行。

在命令提示符下: $ vi filename

然后按“ :”进入命令模式。

全局搜索和替换所有内容是:%s/^M//g“先按住控制键,然后先按V再按M ”,这将不替换^ M。

然后写并退出,输入“ :wq”!


如何在emacs中替换它?
13年

谢谢!VI(M)很棒!
尼卡比曹

3
感谢您介绍如何键入^ M字符!我用\ r代替它。所以我做了:%s / ^ M / \ r / g
aharris88


10

在vi中,执行 :%s/^M//g

^M按住该CTRL键,请按V然后M(按住控制键的同时按两个键),^M将出现。这将查找所有出现的事件,并将其替换为空。


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

8

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

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

当然,您可以使用perl,但是您会建议在dos2unix上使用perl吗?
Thomas Owens

2
我只是提供了一个替代方案,因为已经有四个人说过使用dos2unix。
比尔蜥蜴

2
是的,我发现这很有用,因为我在史前IT部门的办公室中的后向工作站上工作。除我使用的变化过程:perl -pi -e “S / \ X0D / \ N / G” FILE.CSV
Rimian

7

^ M通常是由Windows操作符换行符引起的,并且转换为Unix看起来像^ M。命令dos2unix应该很好地删除它们

dos2unix [选项] [-c convmode] [-o文件...] [-n infile输出文件...]


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

Sed的使用范围更广,如果未安装dos2unix,Sed也可以执行这种操作

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.  

4

要在vi编辑器中替换^ M个字符,请使用以下命令

打开文本文件,说t1.txt

vi t1.txt

通过按进入命令模式 shift + :

然后按上述键 %s/^M/\r/g

in above ^M is not (shift + 6)M instead it is (ctrl + V)(ctrl + M)

您的最后一行是之前所有答案中我所缺少的。我一直没有找到匹配的内容,因为我正在执行shift + 6,所以我做了每个黑客都会做的事,并用自己的解决方案避免了我的误解:记录一个宏,用$结束每一行,然后按x,对文件中的行数重复宏。
darethas

3

dos2unix命令的替代方法是使用标准实用程序,如sed

例如,将dos转换为unix:

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

待办事项:

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

1

您可以通过sed命令直接从文件中删除^ M,例如:

sed -i'.bak' s/\r//g *.*

如果您对更改感到满意,请删除.bak文件:

rm -v *.bak


0

od -a $file 在Linux上探索这些类型的问题很有用(类似于上面的dumphex)。



-1

另一个vi命令将执行:%s/.$// 此操作:删除文件中每行的最后一个字符。该搜索和替换命令的缺点是它并不在乎最后一个字符是什么,因此请注意不要两次调用它。


如果您知道它不可靠,为什么还要提呢?
minexew 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.