首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用sed将CR转换为LF

使用sed将CR转换为LF
EN

Stack Overflow用户
提问于 2017-03-20 21:51:04
回答 2查看 1.4K关注 0票数 4

我在Windows上有一个包含CR和CRLF的文件。

我在上面运行了这个命令:

代码语言:javascript
运行
复制
$ sed -i 's \x0d \x0a ' foo

我得到的是:

  1. 所有没有跟随LF的CR都被转换为LF

  1. 那些属于CRLF的CR没有改变。

为什么会这样呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-20 22:20:40

这种行为的原因是,在unix中以\r结尾的行显示为一行,下一行具有\n

代码语言:javascript
运行
复制
$ echo -e "line1\rline2\r\nline3" |cat -A
line1^Mline2^M$
line3$

因此,在没有g选项的情况下,sed将替换这个“级联”行中的第一个\r:

代码语言:javascript
运行
复制
$ echo -e "line1\rline2\r\nline3" |sed 's \x0d \x0a ' |cat -A
line1$
line2^M$ #this is same input line as line1 and thus \r is not replaced the second time in the same line without g
line3$

如果在同一输入行中发现不止一次\r的全局替换,则需要包含g:

代码语言:javascript
运行
复制
$ echo -e "line1\rline2\r\nline3\rline4\r\nline5\r\nline6" |cat -A
line1^Mline2^M$   #line2 \r will not be replaced without g
line3^Mline4^M$   #line4 \r will not be replaced without g
line5^M$          # This \r will be replaced since it is unique on input line 
line6$

$ echo -e "line1\rline2\r\nline3\rline4\r\nline5\r\nline6" |sed 's \r \n ' |cat -A
line1$
line2^M$
line3$
line4^M$
line5$  #the \r is removed from here even without g , since input line5 was alone
$
line6$

$ echo -e "line1\rline2\r\nline3\rline4\r\nline5\r\nline6" |sed 's \r \n g' |cat -A
line1$
line2$
$
line3$
line4$
$
line5$
$
line6$

注意:

从上面的测试中可以明显看出,用\r替换\n将使CRLF变成LFLF = \n\n,这将生成额外的空行。这可能是可取的,也可能是不可取的。这额外的行可以按建议删除,即通过mklement0的回答

票数 0
EN

Stack Overflow用户

发布于 2017-03-20 22:09:01

假设您在Unix平台上运行这个程序,使用GNU sed

代码语言:javascript
运行
复制
sed -i 's/\r/\n/g; s/\n$//' foo

这将替换所有独立的CR (\r\x0d)实例以及CRLF (\r\n\x0d\x0a)序列,每个都用一个LF (\n\x0a) --参见底部以获得解释。

至于,您尝试了(同样,假设您是在Unix平台上运行它,使用GNU sed):

  • sed以单行的形式读取所有内容,但不包括LF (\n),并在输出时用LF终止该行。
  • 在您的情况下,这意味着一行读取将以CR (\r)结尾(由于sed读取到CR,剥离LF),可能包含该行中的孤立CR实例。
  • 's \x0d \x0a ',由于没有使用g选项,最多用LF替换1 CR字符。

这样做的结果是:

  • 每一行上的第一个CR (\r\x0d)实例应该被LF (\n\x0a)替换
  • 当前行上的任何附加CR实例--包括行结束的CRLF序列的一部分--都将被单独保留。

为什么正确的解决方案需要两个s调用?

  • 's/\r/\n/g'全局(g)用LF \n替换当前行中的所有CR (\r)实例。
  • 因此,由于作为行结束的CR的一部分的CR也被\n所取代,内存中的线(在sed中是模式空间)现在以\n结尾。
  • 因为sed总是在输出中附加LF (\n),所以必须删除额外的尾随\n,这就是s/\n$//'所做的。
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42914599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档