特别是我正在尝试将所有\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解决方案,尽管我可以或多或少地在不同的机器上完成这项工作。
答案 0 :(得分:2)
如果您使用bash
作为shell,则可以使用其ANSI C quoting功能强制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
可用于删除所有回车符,但不仅可用于换行符之前的回车符。)
答案 1 :(得分: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(不处理\ r \ n 正如人们所期望的那样在替换字符串中)。在Mac或其他BSD-ish sed变体上,您应该能够完成 通过指定反斜杠转义的文字(空白)ASCII返回来进行所需的替换 字符。
有关详细信息,请参阅this question。
答案 2 :(得分:1)
sed -e 's/ /\'$'\n/g'
添加了一个新行。
还有另一个选项可以使用'gsed',这是一个更现代的sed版本(与linux相比)。那里你可以使用linux解决方案:sed's / \ r \ n / \ r \ r \ n \ n / g'
答案 3 :(得分:1)
在OSX上执行此操作的一种方法是使用awk :
awk '/\r$/ {printf "%s\r\n", $0}' file
如果您想要仅限sed ,那么这应该适用于OSX:
sed -i.bak "s/"$'\r'"$/&&/" file