这个sed命令如何工作?

时间:2017-01-04 13:49:06

标签: regex sed

我尝试命令sed 's/$/\r/g' linux.txt > linux2win.txt将文本文件从Linux转换为Windows。

它有效!所有\n都转换为\r\n

例如,hello, world \n转换为hello, world \r\n

让我感到困惑的是$究竟指的是什么? \n?或\n之前的空字符?我甚至都不知道我取代了什么。

3 个答案:

答案 0 :(得分:0)

$匹配行尾,因此命令:

sed 's/$/\r/g'

只需将\r添加到行尾,即您所说的内容。如果输入为“hello,world \ r \ n”,则输出为“hello,world \ r \ n”。

答案 1 :(得分:0)

你的问题的前提是有缺陷的。您提供的sed命令将Linux样式的行终止符(仅限换行符)转换为Windows样式(回车符/换行符),而不是相反。

它的工作原理如下:

  • $是一个正则表达式字符,它匹配行的零宽度末尾(即在行终止符之前,如果有的话)。
  • 替换字符串是回车符(表示为\r);它取代了正则表达式匹配的零宽度字符序列,实际上是在换行符之前插入回车符

sed命令中的尾随g指定应替换每行中的所有匹配项;它是多余的,因为每行不能超过一个匹配。

另请注意,这可能有点古怪:如果输入文件没有以换行符结尾,那么输出将以\r结尾,因为文件的末尾是最后一行的结尾

答案 2 :(得分:0)

到目前为止,答案/评论指出$与行尾匹配是误导性的。正则表达式中的$匹配字符串的结尾,即全部。 出现以匹配sed中的行尾的原因是默认情况下sed一次读取1行,因此在该上下文中(但在其他上下文中),它操作的每个字符串都会结束在最后一行。

所以$匹配字符串结尾,如果你的字符串在行尾结束,那么$匹配行的末尾但是如果你的字符串包含多行(例如在sed中)你可以创建一个存储在缓冲区中的多行字符串)然后$在任何给定行的末尾都不匹配,它在字符串的末尾简单且一致地匹配。

同样地,^匹配字符串开头,顺便说一句,而不是你可能听到人们声称的行首。

你的评论:

my original line is hello, world \n$ and $ is invisible , and $ is replaced by \r, now my line is hello, world\n\r$ .`

不,这不是正在发生的事情。您的原始行是:

hello, world\n

和sed一次读取一个\n - 分隔的行,所以读入seds缓冲区的是字符串:

hello, world

现在$是一个与字符串结尾匹配的正则表达式元字符,因此上述字符串$将在d之后匹配(^之前匹配h)所以当你这样做时

s/$/\r/

它将上面的字符串更改为:

hello world\r

然后当sed将其打印出来时,它会添加换行符(因为没有终止换行符的字符串不是每个POSIX的文本行)和输出:

hello world\r\n

请注意,$永远不是字符串的一部分,它只是一个元字符,当在regexp中使用时匹配字符串的结尾,因此您可以测试出现在字符串末尾的字符在字符串结束后执行字符串或执行其他操作(如上所述)。