【问题标题】:Removing Carriage return on Mac OS X using sed使用 sed 在 Mac OS X 上删除回车
【发布时间】:2014-03-04 12:13:10
【问题描述】:

在Linux上删除回车我们可以执行:

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

但同样的不适用于 Mac OS X。需要在前面加上 $ 之类的:

sed -i $'s/\r//' <file>

而且“g”也不需要。

为什么会这样?

【问题讨论】:

  • (假设,我没有 Mac)shell 解释/文件管理。 sed 逐行工作,通常该行由 CR 结束,而不是由 sed 占用。 Linux和mac版不考虑行尾方式相同。如果超过 1 个替换,则需要 g,但默认情况下这始终是最后一个字符。

标签: regex macos sed carriage-return


【解决方案1】:

这是因为 OSX 上的 sed 无法将 \r 识别为特殊字符,这与 Linux 上的 sed 不同。

您可以按照自己的方式使用它:

sed -i.bak $'s/\r//' file

或者这个:

sed -i.bak "s/$(printf '\r')//" file

或者你可以在 OSX 上使用tr

tr -d '\r' < file

【讨论】:

  • 但是替换普通文本就可以了,不需要 "$"..... 所以如果 \r 不被认为是特殊的,即使这样 $ 也不应该是必需的??
  • 只有\n\r需要$前缀
  • 有人能解释一下$ 前缀的作用吗?我理解在大多数 unix shell 中使用 $ 来扩展 shell 变量。我不明白为什么它具有让\r 被 sed 处理为回车的效果。
  • 这是处理反斜杠转义字符的 bash 语法。检查man bash并搜索\$'string'
【解决方案2】:

另一个可移植且灵活的解决方案是:

sed -i.bak $'s/\x0D//' file

因为返回字符的 ASCII 码是 0D。 \x 替换适用于所有 POSIX 版本的 sed,您可以通过查找 ASCII 代码来匹配任何其他麻烦的字符。要查找其他有效替换,请执行 man re_format 或查看 ASCII Table

Linux 需要最后的 /g,因为回车 (\r) 不会结束该行。许多 Windows“纯文本”编辑器(例如记事本)以回车符和换行符 (\r\n) 结束每一行,但 OS 9 (ca. 2001) 或更早版本的 Mac 以“纯文本”文件的每一行结尾用一个 \r。如果您正在清理 Windows 文件,则在任何 *X 系统上都不需要 /g。如果您在 macOS 上,也不需要 /g,因为 macOS 将单个 \r 识别为行尾。

(Linux 系统读取旧的 Mac 文件会认为所有文本都在一个很长的行上,并且只转换第一个 \r。如果您在 Linux 系统上并且需要保留旧的换行符Mac 文件,

sed -i.bak $'s/\x0D/\x0A/g' file

将每个 \r 转换为 \n。)

【讨论】:

    【解决方案3】:

    一个更简单的选择可能是使用perl 而不是sed。它在 Mac 上默认可用,并且显然接受您尝试使用的正常语法:

    perl -i -pe 's/\r//g' $Your_File
    

    如果您真正想要的是用 Unix LF 换行符替换 Windows CRLF 换行符,那么 Perl 的 \R 换行符还有一种更安全的方法:

    perl -i -pe 's/\R/\n/g' $Your_File
    

    perl -i.bak -pe 's/\R/\n/g' $Your_File
    

    这也将保存带有“.bak”扩展名的原始文件

    有关 Perl 的 \R 的详细信息,请参阅 linebreak escape 或 Brian D Foy 的文章:The \R generic line ending,其中甚至还有一些有趣的视频。

    【讨论】:

      猜你喜欢
      • 2012-08-09
      • 2012-12-23
      • 1970-01-01
      • 2019-05-18
      • 1970-01-01
      • 2014-10-19
      • 2010-11-28
      • 2012-02-29
      • 1970-01-01
      相关资源
      最近更新 更多