为什么 sed 's/\r\n/\r/g' 没有按预期工作?
Why doesn't sed 's/\r\n/\r/g' work as expected?
在正常的 windows 到 unix 的转换中,您可以执行类似 sed s/\r//g
的操作,从流中删除 \r 字符。
但我正在尝试转换可能是 mac 编码 (\r) 或 windows 编码 (\r\n) 的文件的结尾。所以我不能只删除 \r,因为它会删除 mac 结尾(如果有的话)。我必须先 "canonicalize" 行结束字符。此规范化步骤从 \r\n 转换为 \r(之后我将 \r 转换为 \n)。然而,我无法用 sed
解决这一步。我试过这样的事情:
$> echo -e "foo\r\nbar" | sed 's/\r\n/\r/g' | xxd -c 24 -g 1
00000000: 66 6f 6f 0d 0a 62 61 72 0a foo..bar.
我是这样用bbe解决的:
$> echo -e "foo\r\nbar" | bbe -e 's/\r\n/\r/g' | xxd -c 24 -g 1
00000000: 66 6f 6f 0d 62 61 72 0a foo.bar.
是否可以用 sed 做同样的事情?
sed
默认在 \n
上拆分输入,因此 \n
永远不会以模式 space 结束。但是,如果您使用 GNU sed
,您可以使用 -z
/--null-data
选项使 sed
将输入视为 NUL
字符分隔行:
$ echo -e "foo\r\nbar" | sed -z 's/\r\n/\r/g' | hd
00000000 66 6f 6f 0d 62 61 72 0a |foo.bar.|
或者,在 POSIX sed
中,您可以将所有行附加到模式 space 中(其中 N
command一个循环),有效地将完整文件复制到模式 space,然后执行替换:
$ echo -e "foo\r\nbar" | sed -n ':a;N;ta; s/\r\n/\r/g; p' | hd
00000000 66 6f 6f 0d 62 61 72 0a |foo.bar.|
您可以使用 perl
,它不会像 sed/awk 那样删除记录分隔符。此解决方案不需要对整个文件进行 slurped
$ echo -e 'foo\r\nbar' | perl -pe 's/\r\n/\r/' | xxd -c 24 -g 1
00000000: 66 6f 6f 0d 62 61 72 0a foo.bar.
请注意,不需要 g
修饰符,因为 \n
每条记录只能出现一次
在正常的 windows 到 unix 的转换中,您可以执行类似 sed s/\r//g
的操作,从流中删除 \r 字符。
但我正在尝试转换可能是 mac 编码 (\r) 或 windows 编码 (\r\n) 的文件的结尾。所以我不能只删除 \r,因为它会删除 mac 结尾(如果有的话)。我必须先 "canonicalize" 行结束字符。此规范化步骤从 \r\n 转换为 \r(之后我将 \r 转换为 \n)。然而,我无法用 sed
解决这一步。我试过这样的事情:
$> echo -e "foo\r\nbar" | sed 's/\r\n/\r/g' | xxd -c 24 -g 1
00000000: 66 6f 6f 0d 0a 62 61 72 0a foo..bar.
我是这样用bbe解决的:
$> echo -e "foo\r\nbar" | bbe -e 's/\r\n/\r/g' | xxd -c 24 -g 1
00000000: 66 6f 6f 0d 62 61 72 0a foo.bar.
是否可以用 sed 做同样的事情?
sed
默认在 \n
上拆分输入,因此 \n
永远不会以模式 space 结束。但是,如果您使用 GNU sed
,您可以使用 -z
/--null-data
选项使 sed
将输入视为 NUL
字符分隔行:
$ echo -e "foo\r\nbar" | sed -z 's/\r\n/\r/g' | hd
00000000 66 6f 6f 0d 62 61 72 0a |foo.bar.|
或者,在 POSIX sed
中,您可以将所有行附加到模式 space 中(其中 N
command一个循环),有效地将完整文件复制到模式 space,然后执行替换:
$ echo -e "foo\r\nbar" | sed -n ':a;N;ta; s/\r\n/\r/g; p' | hd
00000000 66 6f 6f 0d 62 61 72 0a |foo.bar.|
您可以使用 perl
,它不会像 sed/awk 那样删除记录分隔符。此解决方案不需要对整个文件进行 slurped
$ echo -e 'foo\r\nbar' | perl -pe 's/\r\n/\r/' | xxd -c 24 -g 1
00000000: 66 6f 6f 0d 62 61 72 0a foo.bar.
请注意,不需要 g
修饰符,因为 \n
每条记录只能出现一次