ChatGPT解决这个技术问题 Extra ChatGPT

保留行尾

我在 windows 上运行 sed 进行一些替换,我注意到它会自动将行尾转换为 Unix (\n)。是否有一个选项告诉 sed 使用 Windows 行尾 (\r\n) 或者更好地保留文件中的行尾?

注意:我使用来自 unxutils 的 sed:http://unxutils.sourceforge.net/

以下解决方案不适用于 macOS。
我什至走到了这一步,但它仍然没有工作LC_ALL=C perl -i -e 'binmode $STDIN;undef $/;$_=<>;s|http://911coned.com|https://911coned.com|gm;print' education.html
所以实际上上面的命令确实有效,我刚刚在 git diff 程序中发现了一个错误。
您可以使用 sed(没有任何特殊选项)+ unix2dos

J
Joseph Thomson

您可以使用 sed 的 -b 选项使其将文件视为二进制文件。这将解决 cygwin 在 Windows 上的 sed 问题。

示例:sed -b 's/foo/bar/'

如果您希望匹配行尾,请记住匹配、捕获并复制可选的回车符。

示例:sed -b 's/foo\(\r\?\)$/bar\1/'

sed man page

-b --binary 此选项在每个平台上都可用,但仅在操作系统区分文本文件和二进制文件时有效。当进行这样的区分时——如 MS-DOS、Windows、Cygwin 的情况——文本文件由由回车符和换行符分隔的行组成,并且 sed 看不到结尾的 CR。当指定此选项时,sed 将以二进制模式打开输入文件,因此不请求此特殊处理并考虑行以换行结束。


请注意,这不适用于 cygwin 上的 sed -i(对我而言),但您可以解决此问题。感谢您的更新——其他答案是一段时间内关于这个主题的最后一句话。
请注意,此选项不适用于 Mac 上的 sed。
即使使用 sed -i 也适用于我:重要的是如何键入它。虽然 sed -bised -i -b 有效,但 sed -ib 有效:请参阅手册页了解原因(使用 b 作为备份副本的后缀)。
使用:sed -bi 's/foo/bar/'
在 Windows cygwin 中对我不起作用。在 sed 进行更改的行上,行结尾是 Unixy。其余行有窗口行结尾。因此,我的文件混合了具有不同行尾的行。
S
SiegeX

您可以尝试在现有脚本的末尾将 \n 替换为 \r\n,如下所示:

sed 's/foo/bar/;s/$/\r/'

也许

 sed -e 's/foo/bar/' -e 's/$/\r/'

如果上述两种方法都不起作用,您必须查阅您的 sed 版本的特定手册页,以查看是否存在这样的选项。请注意,sed 的 *nix 版本不会在没有被告知的情况下更改行终止符。

另一种替代方法是使用 sedcygwin 版本,不应该有这种不良行为。


cygwin 版本确实有这种不良行为。
如果文件同时包含 \n (0x0A) 和 \r\n (0x0D 0x0A) - 这个建议的解决方案(总是重新注入 \r)会破坏它。
这适用于我使用 MSYS2/MinGW。谢谢@SiegeX。
s
seeker

或者,(cygwin 版本的)perl -pe 似乎没有这个问题。


MacOS 上的 sed 没有 -b 选项,并且存在与原始问题中所述类似的问题。 perl 替代方案没有这个问题,所以感谢您的建议。 sed -i -e 's/<img[^>]*\/>//g' *.xml 将行尾替换为 '\n' perl -i -p -e 's/<img[^>]*\/>//g' *.xml 保留原始行尾
b
buckley

如果您只指定 -b 开关和重定向,则可以抑制 Gnuwin 以弄乱换行符 (win->unix)。使用 -i (内联)开关会搞砸。

例如 sed.exe -b "s/\xFF\xFE//" c:\temp\in.csv > c:\temp\out.csv


my answer 中查看具有工作 -i 模式的版本。
V
Vadzim

我发现 https://github.com/mbuilov/sed-windows 中的 sed-4.4.exe 是纯粹的胜利,因为它

在默认模式下使用 windows CRLF 行尾

在 -b 模式下保留原始行尾

在就地 -i 模式下正常工作

还提供带有 \0 分隔符而不是 \n 的 -z 模式,这有时也很方便

另请参阅 list of sed optionslist of all windows sed ports

请注意,gnuwin32 sed 4.2.1-bi 模式下执行 corrupt line endings,根本没有 -z 模式。