regex 你能解释sed的/$/\r/g '吗?

cigdeys3  于 2023-05-19  发布在  其他
关注(0)|答案(3)|浏览(163)

我尝试使用sed 's/$/\r/g' linux.txt > linux2win.txt命令将文本文件从Linux转换到Windows。
而且它起作用了!所有\n都转换为\r\n
例如,将hello, world \n转换为hello, world \r\n
让我困惑的是,$到底指的是什么?\n?还是\n之前的空字符?我都不知道我换了什么。

csbfibhn

csbfibhn1#

到目前为止,说$匹配行尾的答案/评论是误导性的。regexp中的$匹配字符串的结尾,仅此而已。它出现匹配sed中的行尾的原因是,默认情况下sed一次读取1行,所以在该上下文中(但不是在其他上下文中),它操作的每个字符串都在行尾结束。
所以$匹配字符串的结尾,如果你的字符串在一行的结尾处结束,那么$匹配在该行的结尾处,但是如果你的字符串包含多行(例如:在sed中,你可以创建一个存储在缓冲区中的多行字符串),那么$在任何给定行的末尾都不匹配,它只是简单地和一致地匹配在字符串的末尾。
类似地,^匹配字符串开头,而不是你可能听到的人声称的行开头。
wrt您的评论:

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

现在$是匹配字符串结尾的regexp元字符,因此给定上面的字符串$将匹配d之后(^将匹配h之前),所以当您这样做时

s/$/\r/

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

hello world\r

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

hello world\r\n

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

jogvjijk

jogvjijk2#

$匹配行尾,因此命令:

sed 's/$/\r/g'

简单地将\r添加到行尾,这不是你所说的。如果输入为“hello,world \r\n”,则输出为“hello,world \r\n”。

wecizke3

wecizke33#

你的问题的前提是有缺陷的。您提供的sed命令将Linux风格的行终止符(仅换行符)转换为Windows风格的行终止符(回车/换行符),而不是相反。
它的工作原理是这样的:

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

sed命令中的尾部g指定每行中的所有匹配项都应被替换;这是多余的,因为每行不能有多于一个匹配。
请注意,这可能有点古怪:如果输入文件没有以换行符结束,那么输出将以\r结束,因为文件的结尾就是最后一行的结尾。

相关问题