使用 Mac OS X 上的基本 unix 工具(sed、tr 等)将行结尾转换为其他行结尾

问题描述 投票:0回答:4

特别是我正在尝试将所有

\r\n
转变为
\r\r\n
。这是因为 iCloud 的 IMAP 服务器发送
\r\r\n
破坏了协议和所有敏感性(我唯一的工作理论是他们这样做了,所以他们只能在几年前发布的版本中使用自己的 IMAP 客户端),并且我需要编写单元测试模拟这个。

要使其在标准 Unix 工具中工作非常棘手,因为它们处理行结尾的方式。

sed 's/\r\n/\r\r\n/g'
- 不,什么也没做

sed  's/\r/\r\r/g'
- 也什么也不做

tr
在处理字符串方面没有多大用处;它仅对单个字符进行操作,并且似乎保留了字符数。

我实际上不确定如何使用 Unix 工具来做这么低级的事情。 最坏的情况下,我可以用几行 C 语言来完成此操作,但我想学习如何更标准地执行此操作。

根据 Jim 的回答中的讨论,Mac OS X (BSD) 上的 sed 版本似乎与 Linux 的行为不同。 理想情况下,我需要一个 Mac 解决方案,尽管我或多或少可以在另一台机器上完成此任务。

macos unix sed newline
4个回答
3
投票

如果您使用

bash
作为 shell,则可以使用其 ANSI C 引用 功能来强制 Mac OS X
sed
根据您的需要工作。

sed -e $'s/$/\r\r/'

$'...'
是一个 ANSI C 带引号的字符串。 其中大部分(仅)字符没有改变;两个
\r
序列被字符串中的回车符替换。

例如:

$ sed -e $'s/$/\r\r/' genouterr.sh | odx
0x0000: 23 21 2F 62 69 6E 2F 62 61 73 68 0D 0D 0A 66 6F   #!/bin/bash...fo
0x0010: 72 20 69 20 69 6E 20 7B 30 31 2E 2E 35 30 7D 0D   r i in {01..50}.
0x0020: 0D 0A 64 6F 0D 0D 0A 20 20 65 63 68 6F 20 22 73   ..do...  echo "s
0x0030: 74 64 6F 75 74 20 24 69 22 0D 0D 0A 20 20 65 63   tdout $i"...  ec
0x0040: 68 6F 20 22 73 74 64 65 72 72 20 24 69 22 20 3E   ho "stderr $i" >
0x0050: 26 32 0D 0D 0A 64 6F 6E 65 0D 0D 0A               &2...done...
0x005C:
$

十六进制转储(

odx
是一个自制程序,但我喜欢它的格式)显示每个换行符(0A)之前有两个
\r
(0D)字节,这在原始文件中是不存在的。 显然,十六进制转储程序的选择不会影响
sed
命令和 ANSI C 引用机制的有效性。

如果您需要将 CRLF 更改为 CRCRLF,那么您可以使用:

sed -e $'s/\r$/\r\r/'

如果您想删除回车符,但仅在行尾删除,那么您可以使用:

sed -e $'s/\r\r*$//'

tr
可用于删除所有回车符,但不仅限于换行符之前的回车符。)


2
投票
MacOSX 上的

'sed' 与 Linux 上的行为略有不同。您可能想尝试来自此来源存档链接

的说明
sed -e 's/ /\'$'\n/g'

添加了一个新行。

还有另一种选择使用“gsed”,它是 sed 的更现代版本(与 Linux 相当)。在那里你可能可以使用linux解决方案: sed 's/ / /g'


1
投票

您可以使用行尾锚字符“$”来完成您想要的操作:

% od -c foo
0000000   l   i   n   e   1  \r  \n   l   i   n   e   2  \r  \n   l   i
0000020   n   e   3  \r  \n
0000025
% sed 's/\r$/\r\r/g' < foo > bar
% od -c bar
0000000   l   i   n   e   1  \r  \r  \n   l   i   n   e   2  \r  \r  \n
0000020   l   i   n   e   3  \r  \r  \n
0000030

上面的代码适用于 GNU sed,但不适用于 BSD sed(它不处理 正如人们在替换字符串中所期望的那样)。 在 Mac 或其他 BSD 风格的 sed 变体上,您应该能够完成 通过指定反斜杠转义的literal(空格)ASCII 返回来进行所需的替换 性格。

请参阅此问题了解更多详细信息。


1
投票

在 OSX 上执行此操作的一种方法是使用 awk:

awk '/\r$/ {printf "%s\r\n", $0}' file

如果您只想要

sed 那么这应该适用于 OSX:

sed -i.bak "s/"$'\r'"$/&&/" file
    
© www.soinside.com 2019 - 2024. All rights reserved.