101

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

是什么原因造成的,我该如何解决?

4

17 回答 17

80

它是由 DOS/Windows 行尾字符引起的。正如 Andy Whitfield 所说,Unix 命令 dos2unix 将有助于解决问题。如果您想了解更多信息,可以阅读该命令的手册页。

于 2008-09-15T17:07:05.553 回答
77

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

:set fileformat=unix

:w

于 2008-09-16T15:52:50.107 回答
40

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

基于 Windows 的操作系统,由于其 DOS 传统,将行尾存储为一对字符 - 0x0D0A(回车 + 换行)。基于 Unix 的操作系统只使用0x0A(a line feed )。^M您看到的是(0x0D回车的视觉表示。

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

于 2008-09-15T17:11:29.690 回答
24

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

从命令提示符:$ vi filename

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

全局搜索和替换所有内容是:%s/^M//g按住控制然后按 V 然后按 M ”,这将替换 ^M 什么都没有。

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

于 2008-09-15T17:32:10.703 回答
13

尝试使用 dos2unix 去除 ^M。

于 2008-09-15T17:06:14.167 回答
10

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

要获得^M按住CTRL键,请按Vthen M(同时按住 control 键),^M将出现 。这将找到所有事件并将它们替换为空。

于 2008-09-15T17:10:38.693 回答
8

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

perl -pie 's/\r//g' filename.txt
于 2008-09-15T17:10:14.873 回答
7

^M 通常是由 Windows 运算符换行符引起的,翻译成 Unix 看起来像 ^M。命令 dos2unix 应该很好地删除它们

dos2unix [选项] [-c convmode] [-o file ...] [-n infile outfile ...]

于 2008-09-15T17:08:38.590 回答
5
C:\tmp\text>dos2unix hello.txt helloUNIX.txt

如果没有安装 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.  
于 2008-09-15T18:31:41.650 回答
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)
于 2013-04-17T14:34:08.397 回答
4

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

例如,对 unix 的 dos:

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

unix到dos:

sed 's/$/\r/' unix.txt > dos.txt
于 2013-07-18T07:03:20.100 回答
1

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

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

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

rm -v *.bak
于 2014-02-07T16:05:32.713 回答
1

使用 tr 将 DOS/Windows (\r\n) 行尾转换为 Unix (\n) 行尾:

tr '\r\n' '\n' < dosFile.txt > unixFile.txt

发布关于从 Unix 命令行替换换行符的帖子

于 2014-06-03T20:10:19.297 回答
0

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

于 2008-09-15T19:54:22.450 回答
0

在 Perl 中,如果你不想设置 $/ 变量并使用 chomp() 你也可以这样做:

$var =~ /\r\n//g;

我的两分钱

于 2013-03-07T04:32:19.757 回答
0

如前所述,Windows 程序喜欢用 CRLF 终止行代替\r\nUnix/Linux 标准\n。由于我不需要所有功能,dos2unix因此我通过将以下内容添加到 my 来替换它,~/.bashrc从而删除\r

function win2unix() {
    tmp=$(mktemp) && tr -d '\r' < $1 > $tmp && mv $tmp $1
}

现在,当我想摆脱^M创建的那些字符时,例如当我从 Excel 或 Calc 导出 CSV 文件时,我可以执行以下操作:

win2unix filename.csv

当然,您也可以使用sed或其他东西。顺便说一句,我用cat -e $filename形象化的^M结局。

于 2022-01-21T17:04:20.877 回答
-1

另一个可行的 vi 命令::%s/.$// 这会删除文件中每一行的最后一个字符。这个搜索和替换命令的缺点是它不关心最后一个字符是什么,所以注意不要调用它两次。

于 2008-09-15T18:24:40.357 回答