【问题标题】:remove ^M characters from file using sed使用 sed 从文件中删除 ^M 个字符
【发布时间】:2013-10-24 17:52:20
【问题描述】:

我在文件中有这一行:

ULNET-PA,client_sgcib,broker_keplersecurities
,KEPLER

我试图摆脱那个 ^M(回车)字符,所以我使用了:

sed 's/^M//g'

但是这确实会删除 ^M: 之后的所有内容:

[root@localhost tmp]# vi test
ULNET-PA,client_sgcib,broker_keplersecurities^M,KEPLER

[root@localhost tmp]# sed 's/^M//g' test
ULNET-PA,client_sgcib,broker_keplersecurities

我想要得到的是:

[root@localhost tmp]# vi test
ULNET-PA,client_sgcib,broker_keplersecurities,KEPLER

【问题讨论】:

  • 为什么不在你的表达中使用\n 或\r\n?
  • @fedorqui 这不是^ 和M,而是^M,IIRC,称为control character。
  • 使用 $ tr -d '\015' file2; mv file2 file1
  • 简单的方法是,使用'dos2unix '

标签: sed awk


【解决方案1】:

使用tr:

tr -d '^M' < inputfile

(注意^M字符可以使用Ctrl+VCtrl+M输入)


编辑:作为suggested by Glenn Jackman,如果您使用的是bash,您也可以说:

tr -d $'\r' < inputfile

【讨论】:

  • +1 是最简单的解决方案。另请注意,您可以在 tr 中使用八进制代码,例如 tr -d '\012' 来删除换行符。您可以使用od -bc inputfile 浏览文件中的代码含义和位置。
  • @twalberg 我猜dos2unix 只会从行尾删除 CR。问题中的示例并不能清楚地表明它是否仅出现在行尾。
  • @devnull 我想也许它不是通用的,但我的dos2unix 有几个不同的选项来控制可能合适的转换模式(特别是那些用于处理 Mac 文件的选项,似乎喜欢使用^M 行尾)。对于 OP 当前的问题,这可能不是一个完美的解决方案,但这是一件好事,因此“另请参阅……”。
  • 如果你使用的是bash,你可以写tr -d $'\r'
  • @twalberg => 是的,dos2unix 可以在 Mac 上执行此操作,请参阅下面的answer。
【解决方案2】:

还是同一行:

sed -i 's/^M//g' file

当您键入命令时,对于 ^M,您键入 Ctrl+VCtrl+M

其实如果你已经在 vim 中打开了文件,你可以在 vim 中做:

:%s/^M//g

同样,^M 你输入Ctrl-V Ctrl-M

【讨论】:

  • 按住 Ctrl 并按 V 然后按 M
  • OP 说他想要一个使用 sed 的解决方案。
  • 使用 $ tr -d '\015' file2; mv file2 file1
  • 这有效,请查看此链接了解更多变化:cyberciti.biz/faq/…
【解决方案3】:

您可以简单地使用在大多数 Unix/Linux 系统中都可用的 dos2unix。但是我发现以下 sed 命令更好,因为它删除了 dos2unix 不能的 ^M:

sed 's/\r//g' < input.txt >  output.txt

希望对您有所帮助。

注意:^M 实际上是回车符,在代码中表示为 \r dos2unix 所做的很可能相当于:

sed 's/\r\n/\n/g' < input.txt >  output.txt

当 \r 后面没有紧跟 \n 时,它不会删除它,而是将两者都替换为 \n。对于某些类型的文件,例如我刚刚测试过的文件,这会失败。

【讨论】:

  • 很好的解释!!谢谢!!
  • 确实,很好的解释。您的方法似乎适用于我测试过的任何 dos2unix 失败的实例。
【解决方案4】:
alias dos2unix="sed -i -e 's/'\"\$(printf '\015')\"'//g' "

用法:

dos2unix file

【讨论】:

  • 如何在没有别名的情况下在 shell 脚本中使用此命令?一直抱怨一些语法......就像 \015 char vs ^M 的解决方案
  • @bjm88 我在某处找到了这个:sed 's,'$'\015'',,'
【解决方案5】:

如果 Perl 是一个选项:

perl -i -pe 's/\r\n$/\n/g' file

-i 生成输入文件的 .bak 版本
\r = 回车
\n = 换行
$ = 行尾
s/foo/bar/g = 全局用“bar”代替“foo”

【讨论】:

  • 我如何在 perl 脚本中使用它。 test.pl
  • #!/usr/bin/perl open IN, "",换档;而 ( ) { s/\r\n$/\n/g;打印出; } 逼近);关闭(OUT);
  • test.pl infile outfile
  • 请注意,cmets 中的 test.pl 解决方案不会创建备份文件。相反,它将写入一个单独的文件。
【解决方案6】:

我同意@twalberg(参见上面的accepted answer comments),Mac OSX 上的dos2unix 涵​​盖了这一点,引用man dos2unix:

要在 Mac 模式下运行,请使用命令行选项“-c mac”或使用 命令“mac2unix”或“unix2mac”

我选择了 'mac2unix',它摆脱了我在 2 个 Yosemite (OSX 10.10) Mac 之间的 bash 脚本的 Apple 'Messages' 传输引入的 cmd-visible '^M' 条目!

我在 Mac OSX 上使用流行的 Homebrew 软件包安装程序轻松安装了“dos2unix”,我强烈推荐它,它的配套命令 Cask。

【讨论】:

    【解决方案7】:

    在 awk 中:

    sub(/\r/,"")
    

    如果它在记录的末尾,sub(/\r/,"",$NF) 就足够了。无需扫描整个记录。

    【讨论】:

      【解决方案8】:

      这是更好的实现方式

      tr -d '\015' < inputfile_name > outputfile_name
      

      稍后将文件重命名为原始文件名。

      【讨论】:

        【解决方案9】:

        这是干净和简单的,它的工作原理:

        sed -i 's/\r//g' file
        

        其中\r 当然等同于^M。

        【讨论】:

        • 并非所有sed 变体都能识别转义\r。在最初的 Unix 中,它只是意味着一个普通的r 字符,带有一个不必要的转义,它被简单地忽略了。这仍然是 BSD / macOS 上的行为。
        猜你喜欢
        • 2011-04-01
        • 2016-04-17
        • 2015-05-12
        • 1970-01-01
        • 2018-04-20
        • 2018-06-15
        • 2016-12-30
        • 2012-11-15
        相关资源
        最近更新 更多