【问题标题】:'^M' character at end of lines'^M' 字符在行尾
【发布时间】:2010-09-09 01:10:28
【问题描述】:

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

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

【问题讨论】:

    标签: sql unix newline line-endings os-dependent


    【解决方案1】:

    作为already explained,Windows 程序喜欢用CRLF 终止行,即\r\n 而不是Unix/Linux 标准的\n。由于我不需要 dos2unix 的所有功能,我将其替换为将以下内容添加到我的 ~/.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 的结尾。

    【讨论】:

      【解决方案2】:

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

      :set fileformat=unix

      :w

      【讨论】:

      • 这是一个绝妙的答案。非常感谢。 (保存安装dos2unix,我可能只使用一次的工具)
      • 由于某种原因,这不会删除^Ms。参考文件:/etc/timidity/fluidr3_gm.cfg.
      【解决方案3】:

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

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

      Post about replacing newlines from the Unix command line

      【讨论】:

        【解决方案4】:

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

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

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

        rm -v *.bak
        

        【讨论】:

          【解决方案5】:

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

          从命令提示符:$ vi filename

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

          Search and Replace all Globally is :%s/^M//g "按住 control 然后按 V 然后 M" 将 ^M 替换为空。

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

          【讨论】:

          • 在emacs中如何替换?
          • 感谢您对如何键入 ^M 字符的说明!我会用 \r 代替它。所以我做了:%s/^M/\r/g
          【解决方案6】:

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

          例如, 对 unix 的操作:

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

          unix 到 dos:

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

          【讨论】:

            【解决方案7】:

            要在 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,只是对文件中的行数重复宏。
            【解决方案8】:
            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.  
            

            【讨论】:

              【解决方案9】:

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

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

              我的两分钱

              【讨论】:

                【解决方案10】:

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

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

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

                【讨论】:

                • 我不会说当前版本的 Windows 有任何类型的 DOS 遗产。不过,它们仍然存在兼容性限制。
                • 这是最简单的方法,是你做一个自动转换工具。谢谢
                • 但是为什么^M?为什么是'^'?为什么是“M”?
                • 因为它是一个“控制字符”。 “^”是点击控制键的可视化表示。在其特定字节下方,^ 是编辑器表示它们的方式。
                • 赞成明确且内容丰富的答案。顺便说一句,我刚刚在 Excel“另存为...”中尝试了所有不同的 CSV 选项,但它们都生成了 \r,我可以通过 Linux 上的 ^Mcat -e filename.csv 看到这些选项。还尝试了现在在 Microsoft Store 上的 Apache OpenOffice 中的 Calc,结果相同。结论,为了方便编辑,我将使用 Excel 或 Calc,并在 git commit 之前用 dos2unix 去掉 ^M
                【解决方案11】:

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

                要获得^M,请按住 CTRL 键,按 V 然后按 M(同时按住 control 键)和 @ 987654323@ 将出现。这将找到所有匹配项并将它们替换为空。

                【讨论】:

                • 用 unix 友好的换行符替换 ^M::%s/^M/\r/g
                【解决方案12】:

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

                【讨论】:

                • 明知不可靠为什么还要提?
                【解决方案13】:

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

                【讨论】:

                  【解决方案14】:

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

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

                  【讨论】:

                  • 当然,你可以使用 perl,但你会建议 perl 而不是 dos2unix 吗?
                  • 我只是提供一个替代方案,因为已经有四个人说要使用 dos2unix。
                  • 是的,我发现这很有用,因为我在一个落后的工作站上,在一个史前 IT 部门的办公室工作。除了我使用了一个变体: perl -pi -e "s/\x0D/\n/g" file.csv
                  【解决方案15】:

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

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

                  【讨论】:

                    【解决方案16】:

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

                    【讨论】:

                    • 在某些系统(例如 Ubuntu)上,这个命令的名称是“fromdos”
                    • 安装自制软件后,您可以使用brew install dos2unix 在 OSX 上轻松获取该工具
                    【解决方案17】:

                    尝试使用 dos2unix 去除 ^M。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-03-02
                      • 2019-03-24
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多